@cowwoc/requirements
Version:
A fluent API for enforcing design contracts with automatic message generation.
142 lines • 5.14 kB
JavaScript
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