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