UNPKG

anyid

Version:

A simple and flexible API to generate various kinds of string ID / code.

146 lines 4.57 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const assert_1 = __importDefault(require("assert")); const _ = __importStar(require("lodash")); const encode_1 = require("./encode"); const utils_1 = require("./utils"); class Value { constructor(owner) { this.owner = owner; } set bits(n) { this._bits = n; } get bits() { if (!this._bits) { this._bits = this.owner.sectionBitLength(); } return this._bits; } returnValue(v) { return this.bits ? utils_1.toBuffer(v, Math.ceil(this.bits / 8)) : utils_1.toBuffer(v); } } exports.Value = Value; class Delimiter { constructor(delimiter) { this.delimiter = delimiter; } id(_unused) { return this.delimiter; } } class AnyId { constructor() { this._sections = []; this._values = []; } static use(mixin) { const prototype = AnyId.prototype; Object.getOwnPropertyNames(mixin.prototype).forEach((name) => { prototype[name] = mixin.prototype[name]; }); } get codec() { try { return this._codec ? this._codec : this._parent.codec; } catch (_a) { throw new Error('Missing encode()'); } } id(arg) { if (this.hasValue()) { const { bits, buf } = _.reduceRight(this._values, (result, value) => { const v = value.value(arg); const b = value.bits || v.length * 8; return { bits: b + result.bits, buf: utils_1.concatBits(v, b, result.buf, result.bits) }; }, { bits: 0, buf: Buffer.alloc(0) }); const c = this.codec.encode(buf); if (this._length) { if (c.length > this._length) { return c.substr(c.length - this._length); } if (c.length < this._length) { return _.padStart(c, this._length, this.codec.padChar()); } } return c; } return this._sections.map((section) => section.id(arg)).join(''); } section(anyid) { assert_1.default(!this.hasValue(), 'Do not mix section with value'); anyid._parent = this; this._sections.push(anyid); return this; } delimiter(d) { assert_1.default(!this.hasValue(), 'Do not mix delimiter with value'); this._sections.push(new Delimiter(d)); return this; } encode(charset) { assert_1.default(!this._codec, 'Duplicated encode'); this._codec = encode_1.codec(charset); return this; } length(n) { assert_1.default(!this._length, 'Duplicated length'); assert_1.default(n > 0, 'Length must be larger than zero'); this._length = n; return this; } bits(n) { assert_1.default(n > 0, 'Bit must be larger than zero'); this._bits = n; return this; } addValue(value) { assert_1.default(!this.hasSection(), 'Section/delimiter already exist. Value need to be put inside section'); value.bits = this._bits; this._bits = undefined; this._values.push(value); } lastValue() { return _.last(this._values); } findValueByType(type) { for (const v of this._values) { if (v.constructor.name === type) { return v; } } for (const s of this._sections) { if (s instanceof AnyId) { const v = s.findValueByType(type); if (v) { return v; } } } return this._parent ? this._parent.findValueByType(type) : undefined; } sectionBitLength() { return this._length ? this.codec.bytesForLength(this._length) * 8 : undefined; } hasSection() { return this._sections.length > 0; } hasValue() { return this._values.length > 0; } } exports.AnyId = AnyId; //# sourceMappingURL=core.js.map