import * as Show from './Show'; import { type Show as ShowType } from './Show'; import * as ArrayUtil from '../core/ArrayUtil'; import * as ObjectUtil from '../core/ObjectUtil'; import * as StringUtil from '../core/StringUtil'; import * as Type from '../core/Type'; import * as Pnode from './Pnode'; import { type Pnode as PnodeType } from './Pnode'; export interface Pprint { pprint: (a: A) => PnodeType; } export const pprint = (f: (a: A) => PnodeType): Pprint => ({ pprint: f }); export const render = (a: A, pp: Pprint): string => { const n = pp.pprint(a); return Pnode.render(n); }; export const pprintShow = (show: ShowType): Pprint => pprint((a) => Pnode.single(show.show(a))); export const pprintUndefined: Pprint = pprintShow(Show.showUndefined); export const pprintNull: Pprint = pprintShow(Show.showNull); export const pprintString: Pprint = pprintShow(Show.showString); export const pprintBoolean: Pprint = pprintShow(Show.showBoolean); export const pprintNumber: Pprint = pprintShow(Show.showNumber); export const pprintFunction: Pprint = pprintShow(Show.showFunction); export const pprintStringCtor: Pprint = pprintShow(Show.showStringCtor); export const pprintJsonStringify: Pprint = pprintShow(Show.showJsonStringify); export const pprintArray = (pprintA: Pprint): Pprint> => pprint((xs) => { const c = ArrayUtil.mapDelimit(xs, pprintA.pprint, Pnode.appendEnd(',')); return Pnode.pnode('[', c, ']'); }); export const pprintRecord = (pprintA: Pprint): Pprint> => pprint((r) => { const tuples = ObjectUtil.toTuples(r); const cnode: (t: [string, A]) => PnodeType = ([ k, v ]) => { const pv = pprintA.pprint(v); const start = StringUtil.doubleQuote(k) + ': '; return Pnode.prependStart(start)(pv); }; const c = ArrayUtil.mapDelimit(tuples, cnode, Pnode.appendEnd(',')); return Pnode.pnode('{', c, '}'); }); export const pprintAny: Pprint = pprint((a) => { if (Type.isUndefined(a)) { return pprintUndefined.pprint(a); } else if (Type.isNull(a)) { return pprintNull.pprint(a); } else if (Type.isNumber(a)) { return pprintNumber.pprint(a); } else if (Type.isBoolean(a)) { return pprintBoolean.pprint(a); } else if (Type.isFunction(a)) { return pprintFunction.pprint(a); } else if (Type.isString(a)) { return pprintString.pprint(a); } else if (Type.isArray(a)) { return pprintArray(pprintAny).pprint(a); } else if (Type.isObject(a)) { return pprintRecord(pprintAny).pprint(a); } else { return pprintStringCtor.pprint(a); } });