diff options
author | Louis Pilfold <louis@lpil.uk> | 2023-10-22 14:43:56 +0100 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2023-10-26 12:24:40 +0100 |
commit | b58aea03d84059fbc8ea51ae349fa098a93a82e0 (patch) | |
tree | 3a280536fbedef2eaa0879bbe8484f92706a209c | |
parent | 7a5994ad512f65016c94c49540d1b72f5a5dee61 (diff) | |
download | gleam_stdlib-b58aea03d84059fbc8ea51ae349fa098a93a82e0.tar.gz gleam_stdlib-b58aea03d84059fbc8ea51ae349fa098a93a82e0.zip |
inspect for JS now lives in this package
-rw-r--r-- | src/gleam/string.gleam | 2 | ||||
-rw-r--r-- | src/gleam_stdlib.mjs | 62 |
2 files changed, 63 insertions, 1 deletions
diff --git a/src/gleam/string.gleam b/src/gleam/string.gleam index 97acf4e..39d0e5a 100644 --- a/src/gleam/string.gleam +++ b/src/gleam/string.gleam @@ -960,7 +960,7 @@ pub fn inspect(term: anything) -> String { } @external(erlang, "gleam_stdlib", "inspect") -@external(javascript, "../gleam.mjs", "inspect") +@external(javascript, "../gleam_stdlib.mjs", "inspect") fn do_inspect(term term: anything) -> StringBuilder /// Returns the number of bytes in a `String`. diff --git a/src/gleam_stdlib.mjs b/src/gleam_stdlib.mjs index b2c82c4..8edbe2f 100644 --- a/src/gleam_stdlib.mjs +++ b/src/gleam_stdlib.mjs @@ -8,6 +8,8 @@ import { stringBits, toBitString, NonEmpty, + CustomType, + BitArray, } from "./gleam.mjs"; import { CompileError as RegexCompileError, @@ -781,3 +783,63 @@ export function bitwise_shift_left(x, y) { export function bitwise_shift_right(x, y) { return Number(BigInt(x) >> BigInt(y)); } + +export function inspect(v) { + const t = typeof v; + if (v === true) return "True"; + if (v === false) return "False"; + if (v === null) return "//js(null)"; + if (v === undefined) return "Nil"; + if (t === "string") return JSON.stringify(v); + if (t === "bigint" || t === "number") return v.toString(); + if (Array.isArray(v)) return `#(${v.map(inspect).join(", ")})`; + if (v instanceof List) return inspectList(v); + if (v instanceof UtfCodepoint) return inspectUtfCodepoint(v); + if (v instanceof BitArray) return inspectBitArray(v); + if (v instanceof CustomType) return inspectCustomType(v); + if (v instanceof Set) return `//js(Set(${[...v].map(inspect).join(", ")}))`; + if (v instanceof RegExp) return `//js(${v})`; + if (v instanceof Date) return `//js(Date("${v.toISOString()}"))`; + if (v instanceof Function) { + const args = []; + for (const i of Array(v.length).keys()) + args.push(String.fromCharCode(i + 97)); + return `//fn(${args.join(", ")}) { ... }`; + } + return inspectObject(v); +} + +function inspectObject(v) { + const name = Object.getPrototypeOf(v)?.constructor?.name || "Object"; + const props = []; + for (const k of Object.keys(v)) { + props.push(`${inspect(k)}: ${inspect(v[k])}`); + } + const body = props.length ? " " + props.join(", ") + " " : ""; + const head = name === "Object" ? "" : name + " "; + return `//js(${head}{${body}})`; +} + +function inspectCustomType(record) { + const props = Object.keys(record) + .map((label) => { + const value = inspect(record[label]); + return isNaN(parseInt(label)) ? `${label}: ${value}` : value; + }) + .join(", "); + return props + ? `${record.constructor.name}(${props})` + : record.constructor.name; +} + +export function inspectList(list) { + return `[${list.toArray().map(inspect).join(", ")}]`; +} + +export function inspectBitArray(bits) { + return `<<${Array.from(bits.buffer).join(", ")}>>`; +} + +export function inspectUtfCodepoint(codepoint) { + return `//utfcodepoint(${String.fromCodePoint(codepoint.value)})`; +} |