1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
import { Ok, Error, List, NonEmpty } from "./gleam.mjs";
import { default as Dict } from "./dict.mjs";
import { Some, None } from "./gleam/option.mjs";
import { DecodeError, classify } from "./gleam/dynamic.mjs";
export function strict_index(data, key) {
const int = Number.isInteger(key);
// Dictionaries and dictionary-like objects can be indexed
if (data instanceof Dict || data instanceof WeakMap || data instanceof Map) {
const token = {};
const entry = data.get(key, token);
if (entry === token) return new Ok(new None());
return new Ok(new Some(entry));
}
// The first 3 elements of lists can be indexed
if ((key === 0 || key === 1 || key === 2) && data instanceof List) {
let i = 0;
for (const value of data) {
if (i === key) return new Ok(new Some(value));
i++;
}
return new Error("Indexable");
}
// Arrays and objects can be indexed
if (
(int && Array.isArray(data)) ||
(data && typeof data === "object") ||
(data && Object.getPrototypeOf(data) === Object.prototype)
) {
if (key in data) return new Ok(new Some(data[key]));
return new Ok(new None());
}
return new Error(int ? "Indexable" : "Dict");
}
export function list(data, decode, pushPath, index, emptyList) {
if (!(data instanceof List || Array.isArray(data))) {
let error = new DecodeError("List", classify(data), emptyList);
return [emptyList, List.fromArray([error])];
}
const decoded = [];
for (const element of data) {
const layer = decode(element);
const [out, errors] = layer;
if (errors instanceof NonEmpty) {
const [_, errors] = pushPath(layer, index.toString());
return [emptyList, errors];
}
decoded.push(out);
index++;
}
return [List.fromArray(decoded), emptyList];
}
export function dict(data) {
if (data instanceof Dict) {
return new Ok(data);
}
if (data instanceof Map || data instanceof WeakMap) {
return new Ok(Dict.fromMap(data));
}
if (data == null) {
return new Error("Dict");
}
if (typeof data !== "object") {
return new Error("Dict");
}
const proto = Object.getPrototypeOf(data);
if (proto === Object.prototype || proto === null) {
return new Ok(Dict.fromObject(data));
}
return new Error("Dict");
}
|