UNPKG

@unsplash/sum-types

Version:

Safe, ergonomic, non-generic sum types in TypeScript.

72 lines (71 loc) 2.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.is = exports.deserialize = exports.serialize = exports.create = exports._ = exports.mkConstructor = void 0; const tagKey = "_tag"; const valueKey = "_value"; const mkConstructor = () => (k) => v => ({ [tagKey]: k, [valueKey]: v, }); exports.mkConstructor = mkConstructor; const mkConstructors = () => { const xs = new Map(); return new Proxy({}, { get: (__, tag) => { const f = xs.get(tag); if (f !== undefined) return f; const g = (0, exports.mkConstructor)()(tag); xs.set(tag, g); return g; }, }); }; exports._ = Symbol("@unsplash/sum-types pattern matching wildcard"); const mkMatchW = () => (fs) => (x) => { const tag = x[tagKey]; const g = fs[tag]; if (g !== undefined) return g(x[valueKey]); const h = fs[exports._]; if (h !== undefined) return h(); throw new Error(`Failed to pattern match against tag "${tag}".`); }; const mkMatchXW = () => (fs) => (x) => { const tag = x[tagKey]; if (Object.prototype.hasOwnProperty.call(fs, tag)) return fs[tag]; if (Object.prototype.hasOwnProperty.call(fs, exports._)) return fs[exports._]; throw new Error(`Failed to pattern match against tag "${tag}".`); }; const mkMatch = () => (fs) => (x) => mkMatchW()(fs)(x); const mkMatchX = () => (fs) => (x) => mkMatchXW()(fs)(x); const create = () => ({ mk: mkConstructors(), match: mkMatch(), matchW: mkMatchW(), matchX: mkMatchX(), matchXW: mkMatchXW(), }); exports.create = create; const serialize = (x) => [x[tagKey], x[valueKey]]; exports.serialize = serialize; const deserialize = (x) => (y) => { const k = y[0]; const v = y[1]; return x.mk[k](v); }; exports.deserialize = deserialize; const is = () => (k) => (f) => (x) => { if (x === null || !["object", "function"].includes(typeof x)) return false; const xx = x; if (!(tagKey in xx) || xx[tagKey] !== k) return false; if (!(valueKey in xx) || !f(xx[valueKey])) return false; return true; }; exports.is = is;