alwz
Version: 
Extendable library for typecasting
140 lines • 4.08 kB
JavaScript
import EV from './ErrorValue.mjs';
export function isIS(input) {
    return typeof input === 'function';
}
export function assertIS(input) {
    if (isIS(input))
        return true;
    throw new Converter.InvalidTypeCheckFunction('type check must be a function', input);
}
export function isFallback(input) {
    return typeof input === 'function';
}
export function assertFallback(input) {
    if (isFallback(input))
        return true;
    throw new Converter.InvalidFallbackFunction('fallback must be a function', input);
}
export function isConversion(input) {
    return typeof input === 'function';
}
export function assertConversion(input) {
    if (isConversion(input))
        return true;
    throw new Converter.InvalidConversionFunction('conversion must be a function', input);
}
export class Converter {
    constructor(is, fallback) {
        this.convert = (input) => {
            if (this._is(input))
                return input;
            const type = (typeof input);
            if (type in this._types) {
                const conversion = this._types[type];
                return conversion.call(this, input);
            }
            else {
                for (const is of this._conversions.keys()) {
                    if (is(input)) {
                        const conversion = this._conversions.get(is);
                        return conversion.call(this, input);
                    }
                }
            }
            return this._fallback(input);
        };
        this.is = is;
        this.fallback = fallback;
        this._types = {};
        this._conversions = new Map();
        Object.seal(this);
    }
    get is() {
        return this._is;
    }
    set is(is) {
        assertIS(is);
        this._is = is;
    }
    get fallback() {
        return this._fallback;
    }
    set fallback(fallback) {
        assertFallback(fallback);
        this._fallback = fallback;
    }
    get types() {
        return Object.assign({}, this._types);
    }
    get conversions() {
        return Array.from(this._conversions);
    }
    register(is, conversion) {
        assertIS(is);
        assertConversion(conversion);
        this._conversions.set(is, conversion);
        return this;
    }
    unregister(is) {
        assertIS(is);
        this._conversions.delete(is);
        return this;
    }
    type(name, conversion) {
        if (conversion === undefined) {
            delete this._types[name];
        }
        else {
            assertConversion(conversion);
            this._types[name] = conversion;
        }
        return this;
    }
    undefined(conversion) {
        return this.type('undefined', conversion);
    }
    boolean(conversion) {
        return this.type('boolean', conversion);
    }
    number(conversion) {
        return this.type('number', conversion);
    }
    bigint(conversion) {
        return this.type('bigint', conversion);
    }
    string(conversion) {
        return this.type('string', conversion);
    }
    symbol(conversion) {
        return this.type('symbol', conversion);
    }
    clone() {
        return Converter.build(this._is, this._fallback, this._types, this._conversions);
    }
    static build(is, fallback, types = {}, conversions = []) {
        const converter = new Converter(is, fallback);
        for (const type in types) {
            converter.type(type, types[type]);
        }
        for (const [is, conversion] of conversions) {
            converter.register(is, conversion);
        }
        return converter;
    }
    static assert(input) {
        if (Converter.is(input))
            return true;
        throw new Converter.InvalidConverter('input is not a Converter', input);
    }
}
Converter.InvalidTypeCheckFunction = class extends EV {
};
Converter.InvalidFallbackFunction = class extends EV {
};
Converter.InvalidConversionFunction = class extends EV {
};
Converter.InvalidConverter = class extends EV {
};
Converter.is = (input) => input instanceof Converter;
export default Converter;
//# sourceMappingURL=Converter.mjs.map