UNPKG

@cowwoc/requirements

Version:

A fluent API for enforcing design contracts with automatic message generation.

142 lines 5.14 kB
import { Type, getMapper, quoteString } from "./internal.mjs"; /** * Returns the String representation of an object. */ class StringMappers { /** * The default mapper configuration. */ static DEFAULT = new StringMappers(); typeToMapper; /** * Creates a new instance. If `typeToMapper` is `undefined` the new instance uses the * default mappings. Otherwise, it contains a copy of the `typeToMapper` mappings. * * @param typeToMapper - a mapping from the name of a type to the string representation of its values * @throws TypeError if `typeToMapper` is `undefined` or `null` */ constructor(typeToMapper) { if (typeToMapper === undefined) { this.typeToMapper = new Map(); this.typeToMapper.set(Type.STRING, (value) => quoteString(value)); this.typeToMapper.set(Type.ARRAY, (value, seen) => this.arrayToString(value, seen)); this.typeToMapper.set(Type.namedClass("Set"), (value, seen) => this.setToString(value, seen)); this.typeToMapper.set(Type.namedClass("Map"), (value, seen) => this.mapToString(value, seen)); this.typeToMapper.set(Type.namedClass("Error"), (value) => this.errorToString(value)); this.typeToMapper.set(Type.namedClass("Type"), (value) => value.toString()); } else this.typeToMapper = new Map(typeToMapper); } /** * @param array - an array * @param seen - the objects that we've seen before * @returns the "deep" String representation of the array */ arrayToString(array, seen) { if (seen === undefined) seen = new Set(); // We cannot use Arrays.deepToString(array) because it does not delegate to StringMappers.toString() const elements = []; for (const element of array) { if (element !== null && Array.isArray(element)) { if (!seen.has(element)) { seen.add(element); elements.push(this.valueToString(element, seen)); } else elements.push("..."); } else elements.push(this.valueToString(element, seen)); } return `[${elements.join(", ")}]`; } /** * Returns the string representation of a value using the mappers. * * @param value - a value * @param seen - the objects that we've seen before * @returns the string representation of the value */ valueToString(value, seen) { const mapper = getMapper(value, this.typeToMapper); return mapper(value, seen); } /** * @param set - a Set of elements * @param seen - the objects that we've seen before * @returns the string representation of the set */ setToString(set, seen) { if (seen === undefined) seen = new Set(); return this.orderedToString([...set], seen); } /** * @param list - an ordered list of values * @param seen - the objects that we've seen before * @returns the string representation of `list` */ orderedToString(list, seen) { let joiner = "["; for (const element of list) { if (element === list) joiner += "(this Collection)"; else { const elementToString = getMapper(element, this.typeToMapper); joiner += elementToString(element, seen); } } return joiner + "]"; } /** * @param map - a Map of elements * @param seen - the objects that we've seen before * @returns the String representation of the map */ mapToString(map, seen) { if (seen === undefined) seen = new Set(); return this.mapEntriesToString([...map.entries()], seen); } /** * @param entries - map entries * @param seen - the objects that we've seen before * @returns the String representation of the entries */ mapEntriesToString(entries, seen) { let joiner = "{"; for (const entry of entries) { const key = entry[0]; const value = entry[1]; let keyAsString; if (key === entries) keyAsString = "(this Map)"; else keyAsString = getMapper(key, this.typeToMapper)(key, seen); let valueAsString; if (value === entries) valueAsString = "(this Map)"; else valueAsString = getMapper(value, this.typeToMapper)(value, seen); joiner += `${keyAsString} = ${valueAsString}`; } return joiner + "}"; } /** * @param error - an `Error` * @returns the string representation of the error */ errorToString(error) { if (error.stack === undefined) return ""; return error.stack; } toString(value) { const mapper = getMapper(value, this.typeToMapper); return mapper(value); } } export { StringMappers }; //# sourceMappingURL=StringMappers.mjs.map