import * as ArrayUtil from '../core/ArrayUtil';
import * as ObjectUtil from '../core/ObjectUtil';
import { doubleQuote } from '../core/StringUtil';
/** Display the value as it would appear as a literal value in code.
* Useful for debug output.
*
* Note this is *not* like Java toString.
* So, showString.show("abc") = "'abc'" *not* "abc"
*/
export interface Show {
show: (a: A) => string;
}
export const show = (f: (a: A) => string): Show =>
({ show: f });
export const showConst = (s: string): Show => show(() => s);
export const showStringCtor: Show = show((x) => String(x));
export const showJsonStringify: Show = show((x) => JSON.stringify(x));
export const showUndefined: Show = showConst('undefined');
export const showNull: Show = showConst('null');
export const showBoolean: Show = showStringCtor;
export const showNumber: Show = showStringCtor;
export const showString: Show = show((x) => doubleQuote(x));
export const showFunction: Show = showConst('function() {...}');
export const showArray = (showA: Show): Show> => show((xs) =>
'[' + ArrayUtil.map(xs, showA.show).join(', ') + ']'
);
export const showRecord = (showA: Show): Show> => show((rec) =>
'{' + ObjectUtil.toTuples(rec).map(([ k, v ]) => doubleQuote(k) + ': ' + showA.show(v)).join(', ') + '}'
);