aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Pilfold <louis@lpil.uk>2023-10-22 14:43:56 +0100
committerLouis Pilfold <louis@lpil.uk>2023-10-26 12:24:40 +0100
commitb58aea03d84059fbc8ea51ae349fa098a93a82e0 (patch)
tree3a280536fbedef2eaa0879bbe8484f92706a209c
parent7a5994ad512f65016c94c49540d1b72f5a5dee61 (diff)
downloadgleam_stdlib-b58aea03d84059fbc8ea51ae349fa098a93a82e0.tar.gz
gleam_stdlib-b58aea03d84059fbc8ea51ae349fa098a93a82e0.zip
inspect for JS now lives in this package
-rw-r--r--src/gleam/string.gleam2
-rw-r--r--src/gleam_stdlib.mjs62
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)})`;
+}