2021-03-12 19:41:35 +00:00
|
|
|
import type { Value } from './values';
|
2021-01-07 16:41:46 +00:00
|
|
|
|
2021-01-09 15:21:25 +00:00
|
|
|
export function stringify(x: any): string {
|
2021-01-11 15:54:52 +00:00
|
|
|
if (typeof x?.asPreservesText === 'function') {
|
2021-01-07 16:41:46 +00:00
|
|
|
return x.asPreservesText();
|
|
|
|
} else {
|
2021-01-09 15:21:25 +00:00
|
|
|
try {
|
|
|
|
return JSON.stringify(x);
|
|
|
|
} catch (_e) {
|
|
|
|
return ('' + x).asPreservesText();
|
|
|
|
}
|
2021-01-07 16:41:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-24 19:59:52 +00:00
|
|
|
export function preserves<T>(pieces: TemplateStringsArray, ...values: Value<T>[]): string {
|
2021-01-07 16:41:46 +00:00
|
|
|
const result = [pieces[0]];
|
|
|
|
values.forEach((v, i) => {
|
|
|
|
result.push(stringify(v));
|
|
|
|
result.push(pieces[i + 1]);
|
|
|
|
});
|
|
|
|
return result.join('');
|
|
|
|
}
|
2021-03-04 21:42:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
declare global {
|
|
|
|
interface Object { asPreservesText(): string; }
|
|
|
|
}
|
|
|
|
|
|
|
|
Object.defineProperty(Object.prototype, 'asPreservesText', {
|
|
|
|
enumerable: false,
|
|
|
|
writable: true,
|
2021-04-24 19:59:52 +00:00
|
|
|
value: function(): string {
|
|
|
|
return JSON.stringify(this);
|
|
|
|
}
|
2021-03-04 21:42:40 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
Boolean.prototype.asPreservesText = function (): string {
|
|
|
|
return this ? '#t' : '#f';
|
|
|
|
};
|
|
|
|
|
|
|
|
Number.prototype.asPreservesText = function (): string {
|
|
|
|
return '' + this;
|
|
|
|
};
|
|
|
|
|
|
|
|
String.prototype.asPreservesText = function (): string {
|
|
|
|
return JSON.stringify(this);
|
|
|
|
};
|
|
|
|
|
|
|
|
Symbol.prototype.asPreservesText = function (): string {
|
|
|
|
// TODO: escaping
|
|
|
|
return this.description ?? '||';
|
|
|
|
};
|