"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TypeSafetyUtils = void 0;
const lodash_1 = require("lodash");
class TypeSafetyUtils {
    /** Ensures a type-safe boolean tri-state value `true|false|undefined`,
     * using the `toBoolean()` method on this class.
     *
     * For defined values, performs a hard data conversion to a boolean (not just a cast or a Boolean() call).
     *
     * Converts strings to lowercase while determining and throws if value is anything other than null, undefined, or a valid boolean string ("true", "false", "yes", "no", "0", "1").
     *
     * *This method reflects one of the myriad idiosyncracies of typescript: in this case that there's
     * no reliable built-in converter function (like a `boolean.tryParse()`) for booleans,
     * and we have to waste time and performance rolling and importing and calling our own #$!*$%!@^!!*     */
    static toTriState(value) {
        return (value == undefined) ? undefined : this.toBoolean(value);
    }
    /** Performs a hard data conversion to a boolean (not just a cast or a Boolean() call).
     *
     * Converts strings to lowercase while determining and throws if value is not a valid boolean string ("true", "false", "yes", "no", "0", "1").
     *
     * *This method reflects one of the myriad idiosyncracies of typescript: in this case that there's
     * no reliable built-in converter function (like a `boolean.tryParse()`) for booleans,
     * and we have to waste time and performance rolling and importing and calling our own #$!*$%!@^!!*     */
    static toBoolean(value) {
        if (value == undefined || value == null) {
            return false;
        }
        else if (typeof value == "boolean") {
            return Boolean(value);
        }
        else if ((0, lodash_1.isNumber)(value)) {
            return Boolean(value != 0);
        }
        else if (typeof value == 'string') {
            const result = TypeSafetyUtils.VALID_BOOLEAN_STRINGS.get(value.toLowerCase());
            if (result !== undefined) {
                return result;
            }
            else {
                throw new Error('Invalid boolean string');
            }
        }
        else {
            return Boolean(value); // <-- this is a grab bag.  Who knows what we'll get.
        }
    }
    /** Converts to the given enum value based on comparison of enum VALUE (NOT enum property name).
     * Returns undefined when not recognized.
     *
     * DEVNOTE:  Replaces hasty syntax:
     * ```
     * const asEnum = (str) ? (<any>MyEnum)[str] : undefined;
     * ```
     */
    static toEnum(enumObj, str) {
        if (str === undefined)
            return undefined;
        return Object.values(enumObj).includes(str) ? str : undefined;
    }
}
exports.TypeSafetyUtils = TypeSafetyUtils;
TypeSafetyUtils.VALID_BOOLEAN_STRINGS = new Map([
    ['true', true],
    ['false', false],
    ['yes', true],
    ['no', false],
    ['1', true],
    ['0', false]
]);
//# sourceMappingURL=type-safety-utils.js.map