UNPKG

alwz

Version:

Extendable library for typecasting

140 lines 4.08 kB
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