@rust-js/runtime 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +21 -0
  2. package/index.js +3354 -0
  3. package/package.json +20 -0
package/index.js ADDED
@@ -0,0 +1,3354 @@
1
+ // @rust-js/runtime 0.0.1: the helpers the JS rust-js writes imports (ADR 0103).
2
+ // Generated by `rust-js --runtime-module`. Do not edit.
3
+ export function $traitImpl(cache, keys, make) {
4
+ // Each key is a dictionary or a drop, held weakly: a drop made for one call
5
+ // goes when it does. No drop, `undefined`, is keyed by this function. A
6
+ // const parameter's value is a number or the like, which only a Map holds.
7
+ for (let i = 0; i < keys.length - 1; i++) {
8
+ const key = keys[i] ?? $traitImpl;
9
+ const next = keys[i + 1] ?? $traitImpl;
10
+ const weak = typeof next === "object" || typeof next === "function";
11
+ if (!cache.has(key)) cache.set(key, weak ? new WeakMap() : new Map());
12
+ cache = cache.get(key);
13
+ }
14
+ const key = keys[keys.length - 1] ?? $traitImpl;
15
+ if (!cache.has(key)) cache.set(key, make());
16
+ return cache.get(key);
17
+ }
18
+
19
+ export function $index(items, index) {
20
+ if (index < 0 || index >= items.length) throw new Error(`index out of bounds: the len is ${items.length} but the index is ${index}`);
21
+ return items[index];
22
+ }
23
+
24
+ export function $at(items, index) {
25
+ if (index < 0 || index >= items.length) throw new Error(`index out of bounds: the len is ${items.length} but the index is ${index}`);
26
+ return index;
27
+ }
28
+
29
+ // Shortest round-trip decimal, using exact rational arithmetic.
30
+ // Rust Display uses decimal notation, including for very small/large values.
31
+ // Not JS's `String(x)`, though its digits are also the shortest: when two are
32
+ // equally close, JS takes the even one (1888570120608320.2), and Rust the
33
+ // larger (1888570120608320.3).
34
+ export function $displayF64(value) {
35
+ if (Number.isNaN(value)) return 'NaN';
36
+ if (value === Infinity) return 'inf';
37
+ if (value === -Infinity) return '-inf';
38
+ const sign = value < 0 || Object.is(value, -0) ? '-' : '';
39
+ const x = Math.abs(value);
40
+ if (x === 0) return sign + '0';
41
+
42
+ const bitsView = new DataView(new ArrayBuffer(8));
43
+ bitsView.setFloat64(0, x);
44
+ const bits = bitsView.getBigUint64(0);
45
+ const exponentBits = Number((bits >> 52n) & 2047n);
46
+ const fraction = bits & ((1n << 52n) - 1n);
47
+ const significand = exponentBits === 0 ? fraction : fraction + (1n << 52n);
48
+ const binaryExponent = exponentBits === 0 ? -1074 : exponentBits - 1023 - 52;
49
+ const numerator = binaryExponent >= 0 ? significand << BigInt(binaryExponent) : significand;
50
+ const denominator = binaryExponent < 0 ? 1n << BigInt(-binaryExponent) : 1n;
51
+
52
+ // The floating-point logarithm is only an estimate; correct it exactly.
53
+ let exponent = Math.floor(Math.log10(x));
54
+ const atLeastPowerOfTen = e => e >= 0
55
+ ? numerator >= denominator * 10n ** BigInt(e)
56
+ : numerator * 10n ** BigInt(-e) >= denominator;
57
+ while (!atLeastPowerOfTen(exponent)) exponent--;
58
+ while (atLeastPowerOfTen(exponent + 1)) exponent++;
59
+
60
+ for (let precision = 1; precision <= 17; precision++) {
61
+ const power = exponent - precision + 1;
62
+ const n = power < 0 ? numerator * 10n ** BigInt(-power) : numerator;
63
+ const d = power > 0 ? denominator * 10n ** BigInt(power) : denominator;
64
+ const floor = n / d;
65
+ const rounded = floor + (2n * (n % d) >= d ? 1n : 0n);
66
+ // The rounding interval can be asymmetric at a binary power boundary.
67
+ let best;
68
+ let bestDistance;
69
+ for (const candidate of [rounded, rounded - 1n, rounded + 1n]) {
70
+ if (candidate > 0n && Number(`${candidate}e${power}`) === x) {
71
+ const delta = candidate * d - n;
72
+ const distance = delta < 0n ? -delta : delta;
73
+ if (best === undefined || distance < bestDistance || (distance === bestDistance && candidate > best)) {
74
+ best = candidate;
75
+ bestDistance = distance;
76
+ }
77
+ }
78
+ }
79
+ if (best !== undefined) {
80
+ let digits = best.toString();
81
+ let decimalPower = power;
82
+ while (digits.endsWith('0')) {
83
+ digits = digits.slice(0, -1);
84
+ decimalPower++;
85
+ }
86
+ const point = digits.length + decimalPower;
87
+ const body = point <= 0 ? '0.' + '0'.repeat(-point) + digits
88
+ : point >= digits.length ? digits + '0'.repeat(point - digits.length)
89
+ : digits.slice(0, point) + '.' + digits.slice(point);
90
+ return sign + body;
91
+ }
92
+ }
93
+ throw new Error('No f64 round-trip decimal found');
94
+ }
95
+
96
+ export function $f64Max(a, b) {
97
+ return Number.isNaN(a) ? b : Number.isNaN(b) ? a : Math.max(a, b);
98
+ }
99
+
100
+ export function $f64Min(a, b) {
101
+ return Number.isNaN(a) ? b : Number.isNaN(b) ? a : Math.min(a, b);
102
+ }
103
+
104
+ export function $div(a, b, min) {
105
+ if (b === 0) {
106
+ throw new Error("attempt to divide by zero");
107
+ }
108
+ if (a === min && b === -1) {
109
+ throw new Error("attempt to divide with overflow");
110
+ }
111
+ return a / b;
112
+ }
113
+
114
+ export function $rem(a, b, min) {
115
+ if (b === 0) {
116
+ throw new Error("attempt to calculate the remainder with a divisor of zero");
117
+ }
118
+ if (a === min && b === -1) {
119
+ throw new Error("attempt to calculate the remainder with overflow");
120
+ }
121
+ return a % b;
122
+ }
123
+
124
+ export function $retain(v, keep) {
125
+ let n = 0;
126
+ for (const x of v) {
127
+ if (keep(x)) {
128
+ v[n++] = x;
129
+ }
130
+ }
131
+ v.length = n;
132
+ }
133
+
134
+ export function $debug(v) {
135
+ if (typeof v === "string") {
136
+ return JSON.stringify(v);
137
+ }
138
+ if (Array.isArray(v)) {
139
+ return "[" + v.map($debug).join(", ") + "]";
140
+ }
141
+ if (v === undefined) {
142
+ return "()";
143
+ }
144
+ // A `HashMap` and a `HashSet` (ADR 0059), in braces as Rust shows them.
145
+ if (v instanceof Map) {
146
+ return "{" + [...v].map(([k, x]) => $debug(k) + ": " + $debug(x)).join(", ") + "}";
147
+ }
148
+ if (v instanceof Set) {
149
+ return "{" + [...v].map($debug).join(", ") + "}";
150
+ }
151
+ if (typeof v === "object" && v !== null) {
152
+ return "{ " + Object.entries(v).map(([k, x]) => k + ": " + $debug(x)).join(", ") + " }";
153
+ }
154
+ return String(v);
155
+ }
156
+
157
+ export function $eq(a, b) {
158
+ if (a === b || (a == null && b == null)) {
159
+ return true;
160
+ }
161
+ if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) {
162
+ return false;
163
+ }
164
+ if (Array.isArray(a)) {
165
+ return Array.isArray(b) && a.length === b.length && a.every((x, i) => $eq(x, b[i]));
166
+ }
167
+ const keys = Object.keys(a);
168
+ return keys.length === Object.keys(b).length && keys.every((k) => $eq(a[k], b[k]));
169
+ }
170
+
171
+ // `left` and `right` are their `{:?}` strings already (ADR 0060).
172
+ export function $assertFailed(kind, left, right, message) {
173
+ const op = kind === "Eq" ? "==" : kind === "Ne" ? "!=" : "matches";
174
+ const why = message === undefined ? "" : ": " + message;
175
+ throw new Error("assertion `left " + op + " right` failed" + why + "\n left: " + left + "\n right: " + right);
176
+ }
177
+
178
+ export function $unwrap(value, message = "called `Option::unwrap()` on a `None` value") {
179
+ if (value == null) {
180
+ throw new Error(message);
181
+ }
182
+ return value;
183
+ }
184
+
185
+ // `Some(x)` of a generic `T` (ADR 0051): `x`, unless it looks like `None`,
186
+ // as `undefined`, `null` or such a box does. Then it's a box one deeper.
187
+ export function $some(x) {
188
+ if (x == null) return { $someNone: 0 };
189
+ if (typeof x === "object" && "$someNone" in x) return { $someNone: x.$someNone + 1 };
190
+ return x;
191
+ }
192
+
193
+ // What's in a `$some`: the box one level shallower.
194
+ export function $someValue(x) {
195
+ if (x != null && typeof x === "object" && "$someNone" in x) {
196
+ return x.$someNone === 0 ? undefined : { $someNone: x.$someNone - 1 };
197
+ }
198
+ return x;
199
+ }
200
+
201
+ // `Some` of the item at `index`, or `None` when there's none there.
202
+ export function $someAt(items, index) {
203
+ return index >= 0 && index < items.length ? $some(items[index]) : undefined;
204
+ }
205
+
206
+ // `Vec::pop` of a generic `T`: `None` for an empty one, else `Some` of the last.
207
+ export function $pop(items) {
208
+ return items.length === 0 ? undefined : $some(items.pop());
209
+ }
210
+
211
+ // A Rust iterator of the crate's own as a JS one: its `next` returns the
212
+ // item, or `None` at the end. JS's iterator helpers are lazy, like Rust's
213
+ // adapters, so an endless one is fine until something wants all of it. A
214
+ // generic `next` may box its `Some` (ADR 0051): `boxed` unboxes it.
215
+ export function $iterator(iterator, next, boxed = false) {
216
+ return Iterator.from({
217
+ next() {
218
+ const item = next(iterator);
219
+ if (item == null) {
220
+ return { done: true, value: undefined };
221
+ }
222
+ return { done: false, value: boxed ? $someValue(item) : item };
223
+ }
224
+ });
225
+ }
226
+
227
+ export function $insert(map, key, value) {
228
+ const old = map.get(key);
229
+ map.set(key, value);
230
+ return old;
231
+ }
232
+
233
+ export function $add(set, item) {
234
+ const added = !set.has(item);
235
+ set.add(item);
236
+ return added;
237
+ }
238
+
239
+ export function $remove(map, key) {
240
+ const old = map.get(key);
241
+ map.delete(key);
242
+ return old;
243
+ }
244
+
245
+ export function $repeat(item, count, clone) {
246
+ const result = [];
247
+ if (count > 0) {
248
+ for (let i = 1; i < count; i++) result.push(clone(item));
249
+ result.push(item);
250
+ }
251
+ return result;
252
+ }
253
+
254
+ export function $orInsert(map, key, value) {
255
+ if (!map.has(key)) {
256
+ map.set(key, value);
257
+ }
258
+ return map.get(key);
259
+ }
260
+
261
+ export function $orInsertWith(map, key, make) {
262
+ if (!map.has(key)) {
263
+ map.set(key, make());
264
+ }
265
+ return map.get(key);
266
+ }
267
+
268
+ export function $sortedEntries(map, cmp) {
269
+ return Array.from(map).sort((a, b) => cmp(a[0], b[0]));
270
+ }
271
+
272
+ export function $toDigit(c, radix) {
273
+ const digit = parseInt(c, 36);
274
+ return digit < radix ? digit : undefined;
275
+ }
276
+
277
+ export function $lines(s) {
278
+ const lines = s.split("\n");
279
+ const last = lines.pop();
280
+ const ended = lines.map((line) => (line.endsWith("\r") ? line.slice(0, -1) : line));
281
+ if (last !== "") {
282
+ ended.push(last);
283
+ }
284
+ return ended;
285
+ }
286
+
287
+ export function $splitBy(s, matches) {
288
+ const pieces = [""];
289
+ for (const c of s) {
290
+ if (matches(c)) {
291
+ pieces.push("");
292
+ } else {
293
+ pieces[pieces.length - 1] += c;
294
+ }
295
+ }
296
+ return pieces;
297
+ }
298
+
299
+ export function $pow(base, exp) {
300
+ let result = 1;
301
+ while (exp > 0) {
302
+ if (exp & 1) {
303
+ result = Math.imul(result, base);
304
+ }
305
+ base = Math.imul(base, base);
306
+ exp >>>= 1;
307
+ }
308
+ return result;
309
+ }
310
+
311
+ export function $checkedPow(base, exp, lo, hi) {
312
+ const fits = (x) => x >= lo && x <= hi;
313
+ const result = (x) => (typeof hi === "bigint" ? x : Number(x));
314
+ if (exp === 0) return result(1n);
315
+ let b = BigInt(base);
316
+ let acc = 1n;
317
+ while (exp > 1) {
318
+ if (exp & 1) {
319
+ acc *= b;
320
+ if (!fits(acc)) return undefined;
321
+ }
322
+ exp >>>= 1;
323
+ b *= b;
324
+ if (!fits(b)) return undefined;
325
+ }
326
+ acc *= b;
327
+ return fits(acc) ? result(acc) : undefined;
328
+ }
329
+
330
+ export function $powi(x, n) {
331
+ const reciprocal = n < 0;
332
+ let result = 1;
333
+ while (true) {
334
+ if (n & 1) {
335
+ result *= x;
336
+ }
337
+ n = (n / 2) | 0;
338
+ if (n === 0) {
339
+ break;
340
+ }
341
+ x *= x;
342
+ }
343
+ return reciprocal ? 1 / result : result;
344
+ }
345
+
346
+ export function $round(x) {
347
+ return Math.sign(x) * Math.round(Math.abs(x));
348
+ }
349
+
350
+ export function $checked(value, lo, hi) {
351
+ return value >= lo && value <= hi ? value + 0 : undefined;
352
+ }
353
+
354
+ export function $checkedDiv(a, b, min) {
355
+ return b === 0 || (a === min && b === -1) ? undefined : Math.trunc(a / b) + 0;
356
+ }
357
+
358
+ export function $remEuclid(a, b, min) {
359
+ const r = $rem(a, b, min) + 0;
360
+ return r < 0 ? (b < 0 ? r - b : r + b) : r;
361
+ }
362
+
363
+ export function $divEuclid(a, b, min) {
364
+ const q = Math.trunc($div(a, b, min)) + 0;
365
+ return a % b < 0 ? (b > 0 ? q - 1 : q + 1) : q;
366
+ }
367
+
368
+ export function $trailingZeros(x, bits) {
369
+ return x === 0 ? bits : 31 - Math.clz32(x & -x);
370
+ }
371
+
372
+ export function $countOnes(x) {
373
+ let ones = 0;
374
+ x >>>= 0;
375
+ while (x !== 0) {
376
+ ones += x & 1;
377
+ x >>>= 1;
378
+ }
379
+ return ones;
380
+ }
381
+
382
+ export function $binarySearch(items, x) {
383
+ let size = items.length;
384
+ if (size === 0) {
385
+ return { TAG: "Err", _0: 0 };
386
+ }
387
+ let base = 0;
388
+ while (size > 1) {
389
+ const half = size >>> 1;
390
+ const mid = base + half;
391
+ if (!(items[mid] > x)) {
392
+ base = mid;
393
+ }
394
+ size -= half;
395
+ }
396
+ const found = items[base];
397
+ return found === x ? { TAG: "Ok", _0: base } : { TAG: "Err", _0: base + (found < x ? 1 : 0) };
398
+ }
399
+
400
+ export function $removeOpt(items, index) {
401
+ return index < items.length ? items.splice(index, 1)[0] : undefined;
402
+ }
403
+
404
+ export function $iter(items) {
405
+ return {
406
+ items,
407
+ at: 0,
408
+ next() {
409
+ return this.at < this.items.length ? { value: this.items[this.at++], done: false } : { value: undefined, done: true };
410
+ },
411
+ [Symbol.iterator]() {
412
+ return this;
413
+ },
414
+ };
415
+ }
416
+
417
+ export function $next(it) {
418
+ const step = it.next();
419
+ return step.done ? undefined : step.value;
420
+ }
421
+
422
+ export function $nextSome(it) {
423
+ const step = it.next();
424
+ return step.done ? undefined : $some(step.value);
425
+ }
426
+
427
+ export function $scan(items, init, f) {
428
+ const state = { value: init };
429
+ const out = [];
430
+ for (const item of items) {
431
+ const next = f(state, item);
432
+ if (next === undefined) {
433
+ break;
434
+ }
435
+ out.push(next);
436
+ }
437
+ return out;
438
+ }
439
+
440
+ export class $JsonError extends Error {
441
+ constructor(message, line = 0, column = 0) {
442
+ super(message);
443
+ this.line = line;
444
+ this.column = column;
445
+ }
446
+ }
447
+ export function $jsonError(message) {
448
+ return new $JsonError(message);
449
+ }
450
+ // A float as serde_json writes one: its shortest digits, fixed from 1e-5
451
+ // to 1e15, else `1.5e+16`.
452
+ export function $jsonNumber(x) {
453
+ if (!Number.isFinite(x)) return "null";
454
+ if (x === 0) return Object.is(x, -0) ? "-0.0" : "0.0";
455
+ const [mantissa, exponent] = x.toExponential().split("e");
456
+ const e = Number(exponent);
457
+ if (e < -5 || e > 15) return `${mantissa}e${e < 0 ? "-" : "+"}${Math.abs(e)}`;
458
+ const fixed = String(x);
459
+ return fixed.includes(".") ? fixed : `${fixed}.0`;
460
+ }
461
+
462
+ export function $bigDiv(a, b, min) {
463
+ if (b === 0n) {
464
+ throw new Error("attempt to divide by zero");
465
+ }
466
+ if (a === min && b === -1n) {
467
+ throw new Error("attempt to divide with overflow");
468
+ }
469
+ return a / b;
470
+ }
471
+
472
+ export function $bigRem(a, b, min) {
473
+ if (b === 0n) {
474
+ throw new Error("attempt to calculate the remainder with a divisor of zero");
475
+ }
476
+ if (a === min && b === -1n) {
477
+ throw new Error("attempt to calculate the remainder with overflow");
478
+ }
479
+ return a % b;
480
+ }
481
+
482
+ export function $f64ToInt(x, min, max) {
483
+ if (Number.isNaN(x)) return 0;
484
+ return Math.max(min, Math.min(max, Math.trunc(x))) + 0;
485
+ }
486
+
487
+ export function $f64ToBig(x, min, max) {
488
+ if (Number.isNaN(x)) return 0n;
489
+ if (x <= Number(min)) return min;
490
+ if (x >= Number(max)) return max;
491
+ return BigInt(Math.trunc(x));
492
+ }
493
+
494
+ export function $bigAbs(x) {
495
+ return x < 0n ? -x : x;
496
+ }
497
+
498
+ export function $bigPow(base, exp) {
499
+ let result = 1n;
500
+ base = BigInt.asUintN(64, base);
501
+ for (let e = exp; e > 0; e >>>= 1) {
502
+ if (e & 1) result = BigInt.asUintN(64, result * base);
503
+ base = BigInt.asUintN(64, base * base);
504
+ }
505
+ return result;
506
+ }
507
+
508
+ export function $bigChecked(value, lo, hi) {
509
+ return value >= lo && value <= hi ? value : undefined;
510
+ }
511
+
512
+ export function $bigCheckedDiv(a, b, min) {
513
+ return b === 0n || (a === min && b === -1n) ? undefined : a / b;
514
+ }
515
+
516
+ export function $bigClamp(value, lo, hi) {
517
+ return value < lo ? lo : value > hi ? hi : value;
518
+ }
519
+
520
+ export function $bigRemEuclid(a, b, min) {
521
+ const r = $bigRem(a, b, min);
522
+ return r < 0n ? (b < 0n ? r - b : r + b) : r;
523
+ }
524
+
525
+ export function $bigDivEuclid(a, b, min) {
526
+ const q = $bigDiv(a, b, min);
527
+ if (a % b < 0n) return b > 0n ? q - 1n : q + 1n;
528
+ return q;
529
+ }
530
+
531
+ export function $bigSignum(x) {
532
+ return x > 0n ? 1n : x < 0n ? -1n : 0n;
533
+ }
534
+
535
+ export function $bigCountOnes(x) {
536
+ return BigInt.asUintN(64, x).toString(2).replaceAll("0", "").length;
537
+ }
538
+ export function $bigLeadingZeros(x) {
539
+ const bits = BigInt.asUintN(64, x);
540
+ return bits === 0n ? 64 : 64 - bits.toString(2).length;
541
+ }
542
+ export function $bigTrailingZeros(x) {
543
+ const bits = BigInt.asUintN(64, x).toString(2);
544
+ return x === 0n ? 64 : bits.length - 1 - bits.lastIndexOf("1");
545
+ }
546
+
547
+ export function $bigAbsDiff(a, b) {
548
+ return a > b ? a - b : b - a;
549
+ }
550
+
551
+ export function $bigMax(a, b) {
552
+ return b >= a ? b : a;
553
+ }
554
+ export function $bigMin(a, b) {
555
+ return b < a ? b : a;
556
+ }
557
+
558
+ export function $parseBig(s, min, max) {
559
+ const error = (message) => ({ TAG: "Err", _0: message });
560
+ if (s === "") return error("cannot parse integer from empty string");
561
+ if (!(min < 0n ? /^[+-]?[0-9]+$/ : /^\+?[0-9]+$/).test(s)) return error("invalid digit found in string");
562
+ const n = BigInt(s);
563
+ if (n > max) return error("number too large to fit in target type");
564
+ if (n < min) return error("number too small to fit in target type");
565
+ return { TAG: "Ok", _0: n };
566
+ }
567
+
568
+ export function $bigRange(start, end) {
569
+ const items = [];
570
+ for (let i = start; i < end; i++) items.push(i);
571
+ return items;
572
+ }
573
+
574
+ export function $tryFromInt(x, lo, hi) {
575
+ if (x < lo) return { TAG: "Err", _0: "NegOverflow" };
576
+ if (x > hi) return { TAG: "Err", _0: "PosOverflow" };
577
+ return { TAG: "Ok", _0: typeof hi === "bigint" ? BigInt(x) : Number(x) };
578
+ }
579
+
580
+ export const $printed = ["", ""];
581
+ export function $print(text) {
582
+ $write(text, 0);
583
+ }
584
+ export function $eprint(text) {
585
+ $write(text, 1);
586
+ }
587
+ export function $write(text, error) {
588
+ const stream = globalThis.process?.[error ? "stderr" : "stdout"];
589
+ if (stream?.write) {
590
+ stream.write(text);
591
+ return;
592
+ }
593
+ const log = error ? console.error : console.log;
594
+ const lines = ($printed[error] + text).split("\n");
595
+ const rest = lines.pop();
596
+ for (const line of lines) log(line);
597
+ // What's left unended is written when this task ends, so none is lost.
598
+ if (rest !== "" && $printed[error] === "") {
599
+ queueMicrotask(() => {
600
+ if ($printed[error] !== "") log($printed[error]);
601
+ $printed[error] = "";
602
+ });
603
+ }
604
+ $printed[error] = rest;
605
+ }
606
+
607
+ export function $replace(s, pattern, replacement) {
608
+ if (pattern !== "") return s.replaceAll(pattern, replacement);
609
+ return Array.from(s, (c) => replacement + c).join("") + replacement;
610
+ }
611
+ export function $split(s, pattern) {
612
+ return pattern === "" ? ["", ...s, ""] : s.split(pattern);
613
+ }
614
+
615
+ export function $jsonWriter(pretty) {
616
+ // For each array or object open: whether nothing is in it yet.
617
+ const empty = [];
618
+ const next = (json) => {
619
+ const first = empty[empty.length - 1];
620
+ empty[empty.length - 1] = false;
621
+ if (pretty) json.text += (first ? "\n" : ",\n") + " ".repeat(empty.length);
622
+ else if (!first) json.text += ",";
623
+ };
624
+ const open = (json, bracket) => {
625
+ empty.push(true);
626
+ json.text += bracket;
627
+ };
628
+ const close = (json, bracket) => {
629
+ if (!empty.pop() && pretty) json.text += "\n" + " ".repeat(empty.length);
630
+ json.text += bracket;
631
+ };
632
+ return {
633
+ text: "",
634
+ null() { this.text += "null"; },
635
+ bool(b) { this.text += String(b); },
636
+ int(n) { this.text += String(n); },
637
+ number(x) { this.text += $jsonNumber(x); },
638
+ char(c) { this.text += JSON.stringify(c); },
639
+ string(s) { this.text += JSON.stringify(s); },
640
+ // An externally tagged unit variant: its name.
641
+ variant(name) { this.string(name); },
642
+ beginArray() { open(this, "["); },
643
+ beginTuple() { open(this, "["); },
644
+ beginTupleStruct() { open(this, "["); },
645
+ element() { next(this); },
646
+ endArray() { close(this, "]"); },
647
+ beginObject() { open(this, "{"); },
648
+ key(k) {
649
+ next(this);
650
+ this.text += JSON.stringify(k) + (pretty ? ": " : ":");
651
+ },
652
+ endObject() { close(this, "}"); },
653
+ // `#[serde(flatten)]`: `value`'s entries, among the object's own.
654
+ flat(value, write) { write(value, $jsonFlat(this)); },
655
+ };
656
+ }
657
+ // serde's `FlatMapSerializer`: a struct's or a map's entries go into the
658
+ // object `into` is writing; a variant is an entry of its name; `None` and
659
+ // `()` are nothing; and anything else can't be flattened.
660
+ export function $jsonFlat(into) {
661
+ let depth = 0;
662
+ const top = (what) => {
663
+ if (depth === 0) throw $jsonError(`can only flatten structs and maps (got ${what})`);
664
+ };
665
+ const flat = {
666
+ null() { if (depth > 0) into.null(); },
667
+ bool(b) { top("a boolean"); into.bool(b); },
668
+ int(n) { top("an integer"); into.int(n); },
669
+ number(x) { top("a float"); into.number(x); },
670
+ char(c) { top("a char"); into.char(c); },
671
+ string(s) { top("a string"); into.string(s); },
672
+ variant(name) {
673
+ if (depth > 0) return into.variant(name);
674
+ into.key(name);
675
+ into.null();
676
+ },
677
+ beginArray() { top("a sequence"); depth++; into.beginArray(); },
678
+ beginTuple() { top("a tuple"); depth++; into.beginTuple(); },
679
+ beginTupleStruct() { top("a tuple struct"); depth++; into.beginTupleStruct(); },
680
+ element() { into.element(); },
681
+ endArray() { depth--; into.endArray(); },
682
+ beginObject() { if (depth++ > 0) into.beginObject(); },
683
+ key(k) { into.key(k); },
684
+ endObject() { if (--depth > 0) into.endObject(); },
685
+ flat(value, write) { write(value, $jsonFlat(this)); },
686
+ };
687
+ return flat;
688
+ }
689
+ export function $toJson(value, write, pretty) {
690
+ const json = $jsonWriter(pretty);
691
+ try {
692
+ write(value, json);
693
+ } catch (e) {
694
+ if (e instanceof $JsonError) return { TAG: "Err", _0: { message: e.message, line: e.line, column: e.column } };
695
+ throw e;
696
+ }
697
+ return { TAG: "Ok", _0: json.text };
698
+ }
699
+
700
+ // What serde's impls and derives read, the same whatever they read from:
701
+ // the text (`$JsonReader`), or a value already read (`$JsonContent`), which
702
+ // is how serde reads a tagged or an untagged enum.
703
+ export class $JsonDecoder {
704
+ // An integer type, named as serde names it, from `min` to `max`: a
705
+ // number, or for an `i64` or `u64`, a BigInt (ADR 0086).
706
+ int(name, min, max) {
707
+ return this.deserializeNumber(name, (n) => {
708
+ if (n.kind === "f") throw $jsonError(`invalid type: floating point \`${$jsonNumber(n.value)}\`, expected ${name}`);
709
+ if (n.kind === "u" ? n.value > max : n.value < min) {
710
+ throw $jsonError(`invalid value: integer \`${n.value}\`, expected ${name}`);
711
+ }
712
+ return typeof max === "bigint" ? BigInt(n.value) : Number(n.value);
713
+ });
714
+ }
715
+
716
+ f64() {
717
+ return this.deserializeNumber("f64", (n) => Number(n.value));
718
+ }
719
+
720
+ string() {
721
+ return this.deserializeStr("a string", (s) => s);
722
+ }
723
+
724
+ char() {
725
+ return this.deserializeStr("a character", $jsonChar);
726
+ }
727
+
728
+ // A `&str`, which borrows from the text, so it can't have had an escape.
729
+ borrowedStr() {
730
+ return this.deserializeStr("a borrowed string", (s, borrowed) => {
731
+ if (borrowed) return s;
732
+ throw $jsonError(`invalid type: string ${$debugStr(s)}, expected a borrowed string`);
733
+ });
734
+ }
735
+
736
+ vec(read) {
737
+ return this.deserializeSeq("a sequence", (seq) => {
738
+ const items = [];
739
+ while (seq.next()) items.push(seq.value(read));
740
+ return items;
741
+ });
742
+ }
743
+
744
+ tuple(reads) {
745
+ const expected = `a tuple of size ${reads.length}`;
746
+ return this.deserializeSeq(expected, (seq) => reads.map((read, i) => seq.element(read, i, expected)));
747
+ }
748
+
749
+ array(length, read) {
750
+ const expected = length === 0 ? "an empty array" : `an array of length ${length}`;
751
+ return this.deserializeSeq(expected, (seq) =>
752
+ Array.from({ length }, (_, i) => seq.element(read, i, expected)),
753
+ );
754
+ }
755
+
756
+ map(readKey, read) {
757
+ return this.deserializeMap("a map", (map) => {
758
+ const entries = new Map();
759
+ while (map.next()) {
760
+ const key = readKey(map.key());
761
+ entries.set(key, map.value(read));
762
+ }
763
+ return entries;
764
+ });
765
+ }
766
+
767
+ // A struct's fields: `[name, read]`, or `[[name, ...aliases], read]`, and
768
+ // `missing`, the value it has when it's not there, for `#[serde(default)]`.
769
+ // `build` makes the struct of their values.
770
+ struct(expected, fields, build, options = {}) {
771
+ const visitMap = (map) => this.structMap(map, fields, build, options);
772
+ // With a flattened field, serde reads a struct as a map.
773
+ if (options.flatten) return this.deserializeMap(options.expecting ?? expected, visitMap);
774
+ return this.deserializeStruct(
775
+ options.expecting ?? expected,
776
+ fields.flatMap(([names]) => names),
777
+ visitMap,
778
+ (seq) => this.structSeq(seq, expected, fields, build, options),
779
+ );
780
+ }
781
+
782
+ // `deserialize_struct`: a map, of these `names`, or for most readers, any
783
+ // map at all.
784
+ deserializeStruct(expected, names, visitMap, visitSeq) {
785
+ return this.deserializeMap(expected, visitMap, visitSeq);
786
+ }
787
+
788
+ // An untagged struct variant, which serde reads from an object only.
789
+ untaggedStruct(expected, fields, build, options = {}) {
790
+ return this.deserializeAny(options.expecting ?? expected, {
791
+ map: (map) => this.structMap(map, fields, build, options),
792
+ });
793
+ }
794
+
795
+ // `flatten`: the readers of the flattened fields, which read what the
796
+ // struct's own fields don't, kept until they're all read.
797
+ structMap(map, fields, build, { deny = false, container, flatten } = {}) {
798
+ const values = new Array(fields.length);
799
+ const seen = new Array(fields.length).fill(false);
800
+ const kept = [];
801
+ while (map.next()) {
802
+ const keyContent = map.key().content();
803
+ const key = keyContent.value;
804
+ const i = $jsonField(key, fields, deny && !flatten);
805
+ if (i < 0 && flatten) {
806
+ kept.push([keyContent, map.value((json) => json.content())]);
807
+ continue;
808
+ }
809
+ if (i < 0) {
810
+ map.value((json) => json.ignoreValue());
811
+ continue;
812
+ }
813
+ if (seen[i]) throw $jsonError(`duplicate field \`${$jsonName(fields[i][0])}\``);
814
+ values[i] = map.value(fields[i][1]);
815
+ seen[i] = true;
816
+ }
817
+ const defaults = container?.();
818
+ fields.forEach(([names, read, missing], i) => {
819
+ if (!seen[i]) values[i] = missing ? missing(defaults) : read(new $JsonMissing($jsonName(names)));
820
+ });
821
+ if (!flatten) return build(values, defaults);
822
+ for (const read of flatten) values.push(read(new $JsonFlat(kept)));
823
+ const left = deny && kept.find(Boolean);
824
+ if (left) throw $jsonError(`unknown field \`${left[0].value}\``);
825
+ return build(values, defaults);
826
+ }
827
+
828
+ structSeq(seq, expected, fields, build, { container, expecting } = {}) {
829
+ const length = expecting ?? `${expected} with ${fields.length} element${fields.length === 1 ? "" : "s"}`;
830
+ const defaults = container?.();
831
+ const values = fields.map(([, read, missing], i) => seq.element(read, i, length, missing, defaults));
832
+ return build(values, defaults);
833
+ }
834
+
835
+ // A tuple struct's fields: `read`, or `[read, missing]`.
836
+ tupleStruct(expected, fields, build = (values) => values, { container, expecting } = {}) {
837
+ const length = expecting ?? `${expected} with ${fields.length} element${fields.length === 1 ? "" : "s"}`;
838
+ return this.deserializeSeq(expecting ?? expected, (seq) => {
839
+ const defaults = container?.();
840
+ const values = fields.map((field, i) => {
841
+ const [read, missing] = typeof field === "function" ? [field] : field;
842
+ return seq.element(read, i, length, missing, defaults);
843
+ });
844
+ return build(values, defaults);
845
+ });
846
+ }
847
+
848
+ // An internally tagged enum's unit variant, whose other fields are
849
+ // ignored (serde's `InternallyTaggedUnitVisitor`).
850
+ taggedUnit(expected) {
851
+ return this.deserializeAny(expected, {
852
+ seq: () => undefined,
853
+ map: (map) => {
854
+ while (map.next()) {
855
+ map.key().ignore();
856
+ map.value((json) => json.ignoreValue());
857
+ }
858
+ return undefined;
859
+ },
860
+ });
861
+ }
862
+
863
+ // An untagged unit variant: `null` (serde's `UntaggedUnitVisitor`).
864
+ untaggedUnit(expected) {
865
+ return this.deserializeAny(expected, { unit: () => undefined });
866
+ }
867
+
868
+ // `#[serde(tag = "type")]`: the tag, found among the other fields, which
869
+ // are kept for the variant to read (serde's `TaggedContentVisitor`).
870
+ internallyTagged(tag, expected, variants, visit, other) {
871
+ const [variant, rest] = this.deserializeAny(expected, {
872
+ seq: (seq) => {
873
+ if (!seq.next()) throw $jsonError(`missing field \`${tag}\``);
874
+ const variant = seq.value((json) => json.identifier(variants, other));
875
+ const items = [];
876
+ while (seq.next()) items.push(seq.value((json) => json.content()));
877
+ return [variant, { type: "seq", value: items }];
878
+ },
879
+ map: (map) => {
880
+ let variant;
881
+ const entries = [];
882
+ while (map.next()) {
883
+ const key = map.key().content();
884
+ if (key.value !== tag) {
885
+ entries.push([key, map.value((json) => json.content())]);
886
+ continue;
887
+ }
888
+ if (variant !== undefined) throw $jsonError(`duplicate field \`${tag}\``);
889
+ variant = map.value((json) => json.identifier(variants, other));
890
+ }
891
+ if (variant === undefined) throw $jsonError(`missing field \`${tag}\``);
892
+ return [variant, { type: "map", value: entries }];
893
+ },
894
+ });
895
+ return visit(variant, new $JsonContent(rest, true));
896
+ }
897
+
898
+ // `#[serde(tag = "t", content = "c")]`, as serde's derive reads one: the
899
+ // tag, then the content, or the content first, kept until the tag says
900
+ // how to read it.
901
+ adjacentlyTagged(tag, content, expected, variants, visit, { deny = false, other } = {}) {
902
+ const variantOf = (json) =>
903
+ json.enum(
904
+ undefined,
905
+ variants,
906
+ (name, access) => {
907
+ access.unit();
908
+ return name;
909
+ },
910
+ other,
911
+ );
912
+ // The next key that's the tag or the content, skipping any other.
913
+ const relevant = (map) => {
914
+ while (map.next()) {
915
+ const key = map.key().string();
916
+ if (key === tag) return "tag";
917
+ if (key === content) return "content";
918
+ if (deny) {
919
+ throw $jsonError(`invalid value: string ${$debugStr(key)}, expected ${$debugStr(tag)} or ${$debugStr(content)}`);
920
+ }
921
+ map.value((json) => json.ignoreValue());
922
+ }
923
+ return undefined;
924
+ };
925
+ const finish = (map, value) => {
926
+ const key = relevant(map);
927
+ if (key !== undefined) throw $jsonError(`duplicate field \`${key === "tag" ? tag : content}\``);
928
+ return value;
929
+ };
930
+ return this.deserializeStruct(
931
+ expected,
932
+ [tag, content],
933
+ (map) => {
934
+ const first = relevant(map);
935
+ if (first === "tag") {
936
+ const variant = map.value(variantOf);
937
+ const second = relevant(map);
938
+ if (second === "tag") throw $jsonError(`duplicate field \`${tag}\``);
939
+ if (second === "content") return finish(map, map.value((json) => visit(variant, json)));
940
+ return visit(variant, new $JsonMissing(content));
941
+ }
942
+ if (first === "content") {
943
+ const buffered = map.value((json) => json.content());
944
+ const second = relevant(map);
945
+ if (second === "tag") {
946
+ const variant = map.value(variantOf);
947
+ return finish(map, visit(variant, new $JsonContent(buffered, true)));
948
+ }
949
+ if (second === "content") throw $jsonError(`duplicate field \`${content}\``);
950
+ }
951
+ throw $jsonError(`missing field \`${tag}\``);
952
+ },
953
+ (seq) => {
954
+ if (!seq.next()) throw $jsonError(`invalid length 0, expected ${expected}`);
955
+ const variant = seq.value((json) => json.identifier(variants, other));
956
+ if (!seq.next()) throw $jsonError(`invalid length 1, expected ${expected}`);
957
+ return seq.value((json) => visit(variant, json));
958
+ },
959
+ );
960
+ }
961
+
962
+ // `#[serde(untagged)]`: the value, read once and kept, then each way of
963
+ // reading it in turn, the first that works.
964
+ untagged(message, attempts) {
965
+ const content = this.content();
966
+ for (const attempt of attempts) {
967
+ try {
968
+ return attempt(new $JsonContent(content, false));
969
+ } catch (e) {
970
+ if (!(e instanceof $JsonError)) throw e;
971
+ }
972
+ }
973
+ throw $jsonError(message);
974
+ }
975
+ }
976
+
977
+ // serde_json's reader (ADR 0078): its `Deserializer`, ported step for step,
978
+ // with its methods' names. It reads the text's UTF-8 bytes, as serde_json
979
+ // does, so a mistake is found at the same byte, with the same message, and
980
+ // its column counts bytes.
981
+ export class $JsonReader extends $JsonDecoder {
982
+ constructor(text) {
983
+ super();
984
+ this.bytes = new TextEncoder().encode(text);
985
+ this.index = 0;
986
+ this.remainingDepth = 128;
987
+ }
988
+
989
+ // The next byte, or -1 at the end.
990
+ peek() {
991
+ return this.index < this.bytes.length ? this.bytes[this.index] : -1;
992
+ }
993
+
994
+ next() {
995
+ return this.index < this.bytes.length ? this.bytes[this.index++] : -1;
996
+ }
997
+
998
+ // `position_of_index`: the line, and the bytes before `index` on it.
999
+ errorAt(index, message) {
1000
+ const start = index === 0 ? 0 : this.bytes.lastIndexOf(10, index - 1) + 1;
1001
+ let line = 1;
1002
+ for (let i = 0; i < start; i++) if (this.bytes[i] === 10) line++;
1003
+ return new $JsonError(message, line, index - start);
1004
+ }
1005
+
1006
+ error(message) {
1007
+ return this.errorAt(this.index, message);
1008
+ }
1009
+
1010
+ peekError(message) {
1011
+ return this.errorAt(Math.min(this.bytes.length, this.index + 1), message);
1012
+ }
1013
+
1014
+ // `fix_position`: a visitor's message has no place, until it gets where
1015
+ // the reader is.
1016
+ fixPosition(e) {
1017
+ return e instanceof $JsonError && e.line === 0 ? this.error(e.message) : e;
1018
+ }
1019
+
1020
+ end() {
1021
+ if (this.parseWhitespace() !== -1) throw this.peekError("trailing characters");
1022
+ }
1023
+
1024
+ parseWhitespace() {
1025
+ for (;;) {
1026
+ const c = this.peek();
1027
+ if (c !== 32 && c !== 10 && c !== 9 && c !== 13) return c;
1028
+ this.index++;
1029
+ }
1030
+ }
1031
+
1032
+ parseIdent(rest) {
1033
+ for (let i = 0; i < rest.length; i++) {
1034
+ const c = this.next();
1035
+ if (c === -1) throw this.error("EOF while parsing a value");
1036
+ if (c !== rest.charCodeAt(i)) throw this.error("expected ident");
1037
+ }
1038
+ }
1039
+
1040
+ // What's there instead of `expected`, read past, in serde's words.
1041
+ peekInvalidType(expected) {
1042
+ const c = this.peek();
1043
+ let unexpected;
1044
+ if (c === 110) {
1045
+ this.index++;
1046
+ this.parseIdent("ull");
1047
+ unexpected = "null";
1048
+ } else if (c === 116) {
1049
+ this.index++;
1050
+ this.parseIdent("rue");
1051
+ unexpected = "boolean `true`";
1052
+ } else if (c === 102) {
1053
+ this.index++;
1054
+ this.parseIdent("alse");
1055
+ unexpected = "boolean `false`";
1056
+ } else if (c === 45) {
1057
+ this.index++;
1058
+ unexpected = $jsonUnexpectedNumber(this.parseInteger(false));
1059
+ } else if (c >= 48 && c <= 57) {
1060
+ unexpected = $jsonUnexpectedNumber(this.parseInteger(true));
1061
+ } else if (c === 34) {
1062
+ this.index++;
1063
+ unexpected = `string ${$debugStr(this.parseStr())}`;
1064
+ } else if (c === 91) {
1065
+ unexpected = "sequence";
1066
+ } else if (c === 123) {
1067
+ unexpected = "map";
1068
+ } else {
1069
+ return this.peekError("expected value");
1070
+ }
1071
+ return this.fixPosition($jsonError(`invalid type: ${unexpected}, expected ${expected}`));
1072
+ }
1073
+
1074
+ // A number: `{ kind, value }`, a `"u"`nsigned or `"i"`nteger (a BigInt
1075
+ // past 2^53) where it's an integer that fits in 64 bits, else an `"f"`.
1076
+ deserializeNumber(expected, visit) {
1077
+ const peek = this.parseWhitespace();
1078
+ if (peek === -1) throw this.peekError("EOF while parsing a value");
1079
+ try {
1080
+ if (peek === 45) {
1081
+ this.index++;
1082
+ return visit(this.parseInteger(false));
1083
+ }
1084
+ if (peek >= 48 && peek <= 57) return visit(this.parseInteger(true));
1085
+ throw this.peekInvalidType(expected);
1086
+ } catch (e) {
1087
+ throw this.fixPosition(e);
1088
+ }
1089
+ }
1090
+
1091
+ parseInteger(positive) {
1092
+ const c = this.next();
1093
+ if (c === -1) throw this.error("EOF while parsing a value");
1094
+ if (c === 48) {
1095
+ const p = this.peek();
1096
+ if (p >= 48 && p <= 57) throw this.peekError("invalid number");
1097
+ return this.parseNumber(positive, 0);
1098
+ }
1099
+ if (c < 49 || c > 57) throw this.error("invalid number");
1100
+ let significand = c - 48;
1101
+ for (;;) {
1102
+ const p = this.peek();
1103
+ if (p < 48 || p > 57) return this.parseNumber(positive, significand);
1104
+ const grown = $jsonGrow(significand, p - 48);
1105
+ if (grown > 18446744073709551615n) {
1106
+ return { kind: "f", value: this.parseLongInteger(positive, significand) };
1107
+ }
1108
+ this.index++;
1109
+ significand = grown;
1110
+ }
1111
+ }
1112
+
1113
+ parseNumber(positive, significand) {
1114
+ const p = this.peek();
1115
+ if (p === 46) return { kind: "f", value: this.parseDecimal(positive, significand, 0) };
1116
+ if (p === 101 || p === 69) return { kind: "f", value: this.parseExponent(positive, significand, 0) };
1117
+ if (positive) return { kind: "u", value: significand };
1118
+ // `-0`, and below `i64::MIN`, are floats.
1119
+ if (significand === 0 || significand > 9223372036854775808n) {
1120
+ return { kind: "f", value: -Number(significand) };
1121
+ }
1122
+ return { kind: "i", value: -significand };
1123
+ }
1124
+
1125
+ parseDecimal(positive, significand, exponentBeforeDecimalPoint) {
1126
+ this.index++;
1127
+ let exponentAfterDecimalPoint = 0;
1128
+ for (let p = this.peek(); p >= 48 && p <= 57; p = this.peek()) {
1129
+ const grown = $jsonGrow(significand, p - 48);
1130
+ if (grown > 18446744073709551615n) {
1131
+ const exponent = exponentBeforeDecimalPoint + exponentAfterDecimalPoint;
1132
+ return this.parseDecimalOverflow(positive, significand, exponent);
1133
+ }
1134
+ this.index++;
1135
+ significand = grown;
1136
+ exponentAfterDecimalPoint--;
1137
+ }
1138
+ if (exponentAfterDecimalPoint === 0) {
1139
+ throw this.peekError(this.peek() === -1 ? "EOF while parsing a value" : "invalid number");
1140
+ }
1141
+ const exponent = exponentBeforeDecimalPoint + exponentAfterDecimalPoint;
1142
+ const p = this.peek();
1143
+ return p === 101 || p === 69
1144
+ ? this.parseExponent(positive, significand, exponent)
1145
+ : this.f64FromParts(positive, significand, exponent);
1146
+ }
1147
+
1148
+ parseExponent(positive, significand, startingExp) {
1149
+ this.index++;
1150
+ let positiveExp = true;
1151
+ const sign = this.peek();
1152
+ if (sign === 43) {
1153
+ this.index++;
1154
+ } else if (sign === 45) {
1155
+ this.index++;
1156
+ positiveExp = false;
1157
+ }
1158
+ const c = this.next();
1159
+ if (c === -1) throw this.error("EOF while parsing a value");
1160
+ if (c < 48 || c > 57) throw this.error("invalid number");
1161
+ let exp = c - 48;
1162
+ for (let p = this.peek(); p >= 48 && p <= 57; p = this.peek()) {
1163
+ this.index++;
1164
+ if (exp * 10 + (p - 48) > 2147483647) {
1165
+ return this.parseExponentOverflow(positive, significand == 0, positiveExp);
1166
+ }
1167
+ exp = exp * 10 + (p - 48);
1168
+ }
1169
+ // i32's saturating add and subtract.
1170
+ const finalExp = Math.max(-2147483648, Math.min(2147483647, positiveExp ? startingExp + exp : startingExp - exp));
1171
+ return this.f64FromParts(positive, significand, finalExp);
1172
+ }
1173
+
1174
+ // Not correctly rounded, as serde_json's isn't without its
1175
+ // `float_roundtrip` feature: the significand times or over a power of ten.
1176
+ f64FromParts(positive, significand, exponent) {
1177
+ let f = Number(significand);
1178
+ for (;;) {
1179
+ const pow = $JSON_POW10[Math.abs(exponent)];
1180
+ if (pow !== undefined) {
1181
+ if (exponent >= 0) {
1182
+ f *= pow;
1183
+ if (!Number.isFinite(f)) throw this.error("number out of range");
1184
+ } else {
1185
+ f /= pow;
1186
+ }
1187
+ break;
1188
+ }
1189
+ if (f === 0) break;
1190
+ if (exponent >= 0) throw this.error("number out of range");
1191
+ f /= 1e308;
1192
+ exponent += 308;
1193
+ }
1194
+ return positive ? f : -f;
1195
+ }
1196
+
1197
+ parseLongInteger(positive, significand) {
1198
+ let exponent = 0;
1199
+ for (;;) {
1200
+ const p = this.peek();
1201
+ if (p >= 48 && p <= 57) {
1202
+ this.index++;
1203
+ exponent++;
1204
+ } else if (p === 46) {
1205
+ return this.parseDecimal(positive, significand, exponent);
1206
+ } else if (p === 101 || p === 69) {
1207
+ return this.parseExponent(positive, significand, exponent);
1208
+ } else {
1209
+ return this.f64FromParts(positive, significand, exponent);
1210
+ }
1211
+ }
1212
+ }
1213
+
1214
+ parseDecimalOverflow(positive, significand, exponent) {
1215
+ for (let p = this.peek(); p >= 48 && p <= 57; p = this.peek()) this.index++;
1216
+ const p = this.peek();
1217
+ return p === 101 || p === 69
1218
+ ? this.parseExponent(positive, significand, exponent)
1219
+ : this.f64FromParts(positive, significand, exponent);
1220
+ }
1221
+
1222
+ parseExponentOverflow(positive, zeroSignificand, positiveExp) {
1223
+ if (!zeroSignificand && positiveExp) throw this.error("number out of range");
1224
+ for (let p = this.peek(); p >= 48 && p <= 57; p = this.peek()) this.index++;
1225
+ return positive ? 0 : -0;
1226
+ }
1227
+
1228
+ // A string, after its opening quote. `escaped` says whether it had an
1229
+ // escape, which a borrowed `&str` can't (serde_json's `Reference::Copied`).
1230
+ parseStr() {
1231
+ const bytes = this.bytes;
1232
+ let text = "";
1233
+ let start = this.index;
1234
+ this.escaped = false;
1235
+ for (;;) {
1236
+ while (this.index < bytes.length) {
1237
+ const c = bytes[this.index];
1238
+ if (c === 34 || c === 92 || c < 32) break;
1239
+ this.index++;
1240
+ }
1241
+ if (this.index === bytes.length) throw this.error("EOF while parsing a string");
1242
+ const c = bytes[this.index];
1243
+ if (c === 34) {
1244
+ text += $JSON_UTF8.decode(bytes.subarray(start, this.index));
1245
+ this.index++;
1246
+ return text;
1247
+ }
1248
+ if (c !== 92) {
1249
+ this.index++;
1250
+ throw this.error("control character (\\u0000-\\u001F) found while parsing a string");
1251
+ }
1252
+ text += $JSON_UTF8.decode(bytes.subarray(start, this.index));
1253
+ this.index++;
1254
+ text += this.parseEscape();
1255
+ this.escaped = true;
1256
+ start = this.index;
1257
+ }
1258
+ }
1259
+
1260
+ parseEscape() {
1261
+ const c = this.next();
1262
+ if (c === -1) throw this.error("EOF while parsing a string");
1263
+ switch (c) {
1264
+ case 34:
1265
+ return '"';
1266
+ case 92:
1267
+ return "\\";
1268
+ case 47:
1269
+ return "/";
1270
+ case 98:
1271
+ return "\b";
1272
+ case 102:
1273
+ return "\f";
1274
+ case 110:
1275
+ return "\n";
1276
+ case 114:
1277
+ return "\r";
1278
+ case 116:
1279
+ return "\t";
1280
+ case 117:
1281
+ return this.parseUnicodeEscape();
1282
+ }
1283
+ throw this.error("invalid escape");
1284
+ }
1285
+
1286
+ parseUnicodeEscape() {
1287
+ const n = this.decodeHexEscape();
1288
+ // A trailing surrogate, which serde_json calls a leading one.
1289
+ if (n >= 0xdc00 && n <= 0xdfff) throw this.error("lone leading surrogate in hex escape");
1290
+ if (n < 0xd800 || n > 0xdbff) return String.fromCharCode(n);
1291
+ for (const expected of [92, 117]) {
1292
+ if (this.peek() === -1) throw this.error("EOF while parsing a string");
1293
+ const c = this.bytes[this.index++];
1294
+ if (c !== expected) throw this.error("unexpected end of hex escape");
1295
+ }
1296
+ const n2 = this.decodeHexEscape();
1297
+ if (n2 < 0xdc00 || n2 > 0xdfff) throw this.error("lone leading surrogate in hex escape");
1298
+ return String.fromCharCode(n, n2);
1299
+ }
1300
+
1301
+ decodeHexEscape() {
1302
+ if (this.index + 4 > this.bytes.length) {
1303
+ this.index = this.bytes.length;
1304
+ throw this.error("EOF while parsing a string");
1305
+ }
1306
+ let n = 0;
1307
+ let valid = true;
1308
+ for (let i = 0; i < 4; i++) {
1309
+ const digit = $jsonHexDigit(this.bytes[this.index + i]);
1310
+ valid &&= digit >= 0;
1311
+ n = n * 16 + digit;
1312
+ }
1313
+ this.index += 4;
1314
+ if (!valid) throw this.error("invalid escape");
1315
+ return n;
1316
+ }
1317
+
1318
+ ignoreStr() {
1319
+ const bytes = this.bytes;
1320
+ for (;;) {
1321
+ while (this.index < bytes.length) {
1322
+ const c = bytes[this.index];
1323
+ if (c === 34 || c === 92 || c < 32) break;
1324
+ this.index++;
1325
+ }
1326
+ if (this.index === bytes.length) throw this.error("EOF while parsing a string");
1327
+ const c = bytes[this.index];
1328
+ if (c === 34) {
1329
+ this.index++;
1330
+ return;
1331
+ }
1332
+ if (c !== 92) throw this.error("control character (\\u0000-\\u001F) found while parsing a string");
1333
+ this.index++;
1334
+ const escape = this.next();
1335
+ if (escape === -1) throw this.error("EOF while parsing a string");
1336
+ if (escape === 117) this.decodeHexEscape();
1337
+ else if (!'"\\/bfnrt'.includes(String.fromCharCode(escape))) throw this.error("invalid escape");
1338
+ }
1339
+ }
1340
+
1341
+ parseObjectColon() {
1342
+ const c = this.parseWhitespace();
1343
+ if (c === 58) {
1344
+ this.index++;
1345
+ return;
1346
+ }
1347
+ throw this.peekError(c === -1 ? "EOF while parsing an object" : "expected `:`");
1348
+ }
1349
+
1350
+ endSeq() {
1351
+ const c = this.parseWhitespace();
1352
+ if (c === 93) {
1353
+ this.index++;
1354
+ return;
1355
+ }
1356
+ if (c === 44) {
1357
+ this.index++;
1358
+ throw this.peekError(this.parseWhitespace() === 93 ? "trailing comma" : "trailing characters");
1359
+ }
1360
+ throw this.peekError(c === -1 ? "EOF while parsing a list" : "trailing characters");
1361
+ }
1362
+
1363
+ endMap() {
1364
+ const c = this.parseWhitespace();
1365
+ if (c === 125) {
1366
+ this.index++;
1367
+ return;
1368
+ }
1369
+ throw this.peekError(c === 44 ? "trailing comma" : c === -1 ? "EOF while parsing an object" : "trailing characters");
1370
+ }
1371
+
1372
+ ignoreValue() {
1373
+ const frames = [];
1374
+ let enclosing;
1375
+ for (;;) {
1376
+ const peek = this.parseWhitespace();
1377
+ if (peek === -1) throw this.peekError("EOF while parsing a value");
1378
+ let frame;
1379
+ if (peek === 110) {
1380
+ this.index++;
1381
+ this.parseIdent("ull");
1382
+ } else if (peek === 116) {
1383
+ this.index++;
1384
+ this.parseIdent("rue");
1385
+ } else if (peek === 102) {
1386
+ this.index++;
1387
+ this.parseIdent("alse");
1388
+ } else if (peek === 45) {
1389
+ this.index++;
1390
+ this.ignoreInteger();
1391
+ } else if (peek >= 48 && peek <= 57) {
1392
+ this.ignoreInteger();
1393
+ } else if (peek === 34) {
1394
+ this.index++;
1395
+ this.ignoreStr();
1396
+ } else if (peek === 91 || peek === 123) {
1397
+ if (enclosing !== undefined) frames.push(enclosing);
1398
+ enclosing = undefined;
1399
+ this.index++;
1400
+ frame = peek;
1401
+ } else {
1402
+ throw this.peekError("expected value");
1403
+ }
1404
+ let acceptComma = true;
1405
+ if (frame !== undefined) {
1406
+ acceptComma = false;
1407
+ } else if (enclosing !== undefined) {
1408
+ frame = enclosing;
1409
+ enclosing = undefined;
1410
+ } else if (frames.length > 0) {
1411
+ frame = frames.pop();
1412
+ } else {
1413
+ return;
1414
+ }
1415
+ for (;;) {
1416
+ const c = this.parseWhitespace();
1417
+ if (c === 44 && acceptComma) {
1418
+ this.index++;
1419
+ break;
1420
+ }
1421
+ if (c === -1) throw this.peekError(frame === 91 ? "EOF while parsing a list" : "EOF while parsing an object");
1422
+ if (!((c === 93 && frame === 91) || (c === 125 && frame === 123))) {
1423
+ if (acceptComma) throw this.peekError(frame === 91 ? "expected `,` or `]`" : "expected `,` or `}`");
1424
+ break;
1425
+ }
1426
+ this.index++;
1427
+ if (frames.length === 0) return;
1428
+ frame = frames.pop();
1429
+ acceptComma = true;
1430
+ }
1431
+ if (frame === 123) {
1432
+ const quote = this.parseWhitespace();
1433
+ if (quote !== 34) throw this.peekError(quote === -1 ? "EOF while parsing an object" : "key must be a string");
1434
+ this.index++;
1435
+ this.ignoreStr();
1436
+ const colon = this.parseWhitespace();
1437
+ if (colon !== 58) throw this.peekError(colon === -1 ? "EOF while parsing an object" : "expected `:`");
1438
+ this.index++;
1439
+ }
1440
+ enclosing = frame;
1441
+ }
1442
+ }
1443
+
1444
+ ignoreInteger() {
1445
+ const c = this.next();
1446
+ if (c === 48) {
1447
+ const p = this.peek();
1448
+ if (p >= 48 && p <= 57) throw this.peekError("invalid number");
1449
+ } else if (c >= 49 && c <= 57) {
1450
+ for (let p = this.peek(); p >= 48 && p <= 57; p = this.peek()) this.index++;
1451
+ } else {
1452
+ throw this.error("invalid number");
1453
+ }
1454
+ const p = this.peek();
1455
+ if (p === 46) this.ignoreDecimal();
1456
+ else if (p === 101 || p === 69) this.ignoreExponent();
1457
+ }
1458
+
1459
+ ignoreDecimal() {
1460
+ this.index++;
1461
+ let atLeastOneDigit = false;
1462
+ for (let p = this.peek(); p >= 48 && p <= 57; p = this.peek()) {
1463
+ this.index++;
1464
+ atLeastOneDigit = true;
1465
+ }
1466
+ if (!atLeastOneDigit) throw this.peekError("invalid number");
1467
+ const p = this.peek();
1468
+ if (p === 101 || p === 69) this.ignoreExponent();
1469
+ }
1470
+
1471
+ ignoreExponent() {
1472
+ this.index++;
1473
+ const sign = this.peek();
1474
+ if (sign === 43 || sign === 45) this.index++;
1475
+ const c = this.next();
1476
+ if (c < 48 || c > 57) throw this.error("invalid number");
1477
+ for (let p = this.peek(); p >= 48 && p <= 57; p = this.peek()) this.index++;
1478
+ }
1479
+
1480
+ // An array or an object: `visit` reads what's inside, and the closing
1481
+ // bracket is looked for even when it fails, as serde_json does.
1482
+ nested(visit, end) {
1483
+ if (--this.remainingDepth === 0) throw this.peekError("recursion limit exceeded");
1484
+ this.index++;
1485
+ let value;
1486
+ let failure;
1487
+ try {
1488
+ value = visit();
1489
+ } catch (e) {
1490
+ if (!(e instanceof $JsonError)) throw e;
1491
+ failure = e;
1492
+ }
1493
+ this.remainingDepth++;
1494
+ try {
1495
+ end();
1496
+ } catch (e) {
1497
+ if (!(e instanceof $JsonError)) throw e;
1498
+ failure ??= e;
1499
+ }
1500
+ if (failure) throw failure;
1501
+ return value;
1502
+ }
1503
+
1504
+ // `deserialize_seq`: `[ .. ]`, which `visit` reads with a `$JsonSeq`.
1505
+ deserializeSeq(expected, visit) {
1506
+ const peek = this.parseWhitespace();
1507
+ if (peek === -1) throw this.peekError("EOF while parsing a value");
1508
+ try {
1509
+ if (peek !== 91) throw this.peekInvalidType(expected);
1510
+ return this.nested(() => visit(new $JsonSeq(this)), () => this.endSeq());
1511
+ } catch (e) {
1512
+ throw this.fixPosition(e);
1513
+ }
1514
+ }
1515
+
1516
+ // `deserialize_map` and `deserialize_struct`: `{ .. }`, or for a struct,
1517
+ // `[ .. ]` too.
1518
+ deserializeMap(expected, visitMap, visitSeq) {
1519
+ const peek = this.parseWhitespace();
1520
+ if (peek === -1) throw this.peekError("EOF while parsing a value");
1521
+ try {
1522
+ if (peek === 91 && visitSeq) return this.nested(() => visitSeq(new $JsonSeq(this)), () => this.endSeq());
1523
+ if (peek !== 123) throw this.peekInvalidType(expected);
1524
+ return this.nested(() => visitMap(new $JsonMap(this)), () => this.endMap());
1525
+ } catch (e) {
1526
+ throw this.fixPosition(e);
1527
+ }
1528
+ }
1529
+
1530
+ deserializeStr(expected, visit) {
1531
+ const peek = this.parseWhitespace();
1532
+ if (peek === -1) throw this.peekError("EOF while parsing a value");
1533
+ try {
1534
+ if (peek !== 34) throw this.peekInvalidType(expected);
1535
+ this.index++;
1536
+ const s = this.parseStr();
1537
+ return visit(s, !this.escaped);
1538
+ } catch (e) {
1539
+ throw this.fixPosition(e);
1540
+ }
1541
+ }
1542
+
1543
+ // What serde's own impls read, from the text.
1544
+
1545
+ bool() {
1546
+ const peek = this.parseWhitespace();
1547
+ if (peek === -1) throw this.peekError("EOF while parsing a value");
1548
+ try {
1549
+ if (peek === 116) {
1550
+ this.index++;
1551
+ this.parseIdent("rue");
1552
+ return true;
1553
+ }
1554
+ if (peek === 102) {
1555
+ this.index++;
1556
+ this.parseIdent("alse");
1557
+ return false;
1558
+ }
1559
+ throw this.peekInvalidType("a boolean");
1560
+ } catch (e) {
1561
+ throw this.fixPosition(e);
1562
+ }
1563
+ }
1564
+
1565
+ unit(expected = "unit") {
1566
+ const peek = this.parseWhitespace();
1567
+ if (peek === -1) throw this.peekError("EOF while parsing a value");
1568
+ try {
1569
+ if (peek !== 110) throw this.peekInvalidType(expected);
1570
+ this.index++;
1571
+ this.parseIdent("ull");
1572
+ return undefined;
1573
+ } catch (e) {
1574
+ throw this.fixPosition(e);
1575
+ }
1576
+ }
1577
+
1578
+ unitStruct(expected) {
1579
+ return this.unit(expected);
1580
+ }
1581
+
1582
+ option(read) {
1583
+ if (this.parseWhitespace() !== 110) return read(this);
1584
+ this.index++;
1585
+ this.parseIdent("ull");
1586
+ return undefined;
1587
+ }
1588
+
1589
+ // `deserialize_any`: whatever's there, for the `visitor` method of its
1590
+ // kind (`unit`, `bool`, `number`, `string`, `seq` or `map`), which is
1591
+ // `expected` if the visitor has none.
1592
+ deserializeAny(expected, visitor) {
1593
+ const peek = this.parseWhitespace();
1594
+ if (peek === -1) throw this.peekError("EOF while parsing a value");
1595
+ const invalid = (unexpected) => $jsonError(`invalid type: ${unexpected}, expected ${expected}`);
1596
+ try {
1597
+ if (peek === 110) {
1598
+ this.index++;
1599
+ this.parseIdent("ull");
1600
+ if (visitor.unit) return visitor.unit();
1601
+ throw invalid("null");
1602
+ }
1603
+ if (peek === 116 || peek === 102) {
1604
+ this.index++;
1605
+ this.parseIdent(peek === 116 ? "rue" : "alse");
1606
+ if (visitor.bool) return visitor.bool(peek === 116);
1607
+ throw invalid(`boolean \`${peek === 116}\``);
1608
+ }
1609
+ if (peek === 45 || (peek >= 48 && peek <= 57)) {
1610
+ if (peek === 45) this.index++;
1611
+ const n = this.parseInteger(peek !== 45);
1612
+ if (visitor.number) return visitor.number(n);
1613
+ throw invalid($jsonUnexpectedNumber(n));
1614
+ }
1615
+ if (peek === 34) {
1616
+ this.index++;
1617
+ const s = this.parseStr();
1618
+ if (visitor.string) return visitor.string(s, !this.escaped);
1619
+ throw invalid(`string ${$debugStr(s)}`);
1620
+ }
1621
+ if (peek === 91) {
1622
+ return this.nested(() => {
1623
+ if (!visitor.seq) throw invalid("sequence");
1624
+ return visitor.seq(new $JsonSeq(this));
1625
+ }, () => this.endSeq());
1626
+ }
1627
+ if (peek === 123) {
1628
+ return this.nested(() => {
1629
+ if (!visitor.map) throw invalid("map");
1630
+ return visitor.map(new $JsonMap(this));
1631
+ }, () => this.endMap());
1632
+ }
1633
+ throw this.peekError("expected value");
1634
+ } catch (e) {
1635
+ throw this.fixPosition(e);
1636
+ }
1637
+ }
1638
+
1639
+ // serde's `ContentVisitor`: the value, read into a `{ type, value }`.
1640
+ content() {
1641
+ return this.deserializeAny("any value", {
1642
+ unit: () => ({ type: "unit" }),
1643
+ bool: (value) => ({ type: "bool", value }),
1644
+ number: (value) => ({ type: "num", value }),
1645
+ string: (value, borrowed) => ({ type: "str", value, borrowed }),
1646
+ seq: (seq) => {
1647
+ const items = [];
1648
+ while (seq.next()) items.push(seq.value((json) => json.content()));
1649
+ return { type: "seq", value: items };
1650
+ },
1651
+ map: (map) => {
1652
+ const entries = [];
1653
+ while (map.next()) {
1654
+ const key = map.key().content();
1655
+ entries.push([key, map.value((json) => json.content())]);
1656
+ }
1657
+ return { type: "map", value: entries };
1658
+ },
1659
+ });
1660
+ }
1661
+
1662
+ // `deserialize_enum`: `"Name"`, or `{"Name": ..}`. `visit` gets the
1663
+ // variant's name and a `$JsonVariant` to read what it holds. `enumName` is
1664
+ // the enum's, for a flattened one.
1665
+ enum(enumName, variants, visit, other) {
1666
+ const peek = this.parseWhitespace();
1667
+ if (peek === 34) return visit(this.identifier(variants, other), new $JsonVariant(this, true));
1668
+ if (peek !== 123) throw this.peekError(peek === -1 ? "EOF while parsing a value" : "expected value");
1669
+ if (--this.remainingDepth === 0) throw this.peekError("recursion limit exceeded");
1670
+ this.index++;
1671
+ let value;
1672
+ try {
1673
+ const c = this.parseWhitespace();
1674
+ if (c !== 34) {
1675
+ throw this.peekError(
1676
+ c === 125 ? "expected value" : c === -1 ? "EOF while parsing an object" : "key must be a string",
1677
+ );
1678
+ }
1679
+ const name = this.identifier(variants, other);
1680
+ this.parseObjectColon();
1681
+ value = visit(name, new $JsonVariant(this, false));
1682
+ } finally {
1683
+ this.remainingDepth++;
1684
+ }
1685
+ const c = this.parseWhitespace();
1686
+ if (c === 125) {
1687
+ this.index++;
1688
+ return value;
1689
+ }
1690
+ throw this.error(c === -1 ? "EOF while parsing an object" : "expected value");
1691
+ }
1692
+
1693
+ // A variant's name, from a string.
1694
+ identifier(variants, other) {
1695
+ return this.deserializeStr("variant identifier", (name) => $jsonVariantNamed(name, variants, other));
1696
+ }
1697
+ }
1698
+
1699
+ // A value already read (serde's `ContentDeserializer`, or when not `owned`,
1700
+ // its `ContentRefDeserializer`): `{ type, value }`, where `type` is `unit`,
1701
+ // `bool`, `num`, `str`, `seq` or `map`.
1702
+ export class $JsonContent extends $JsonDecoder {
1703
+ constructor(content, owned) {
1704
+ super();
1705
+ this.data = content;
1706
+ this.owned = owned;
1707
+ }
1708
+
1709
+ invalid(expected) {
1710
+ return $jsonError(`invalid type: ${$jsonUnexpectedContent(this.data)}, expected ${expected}`);
1711
+ }
1712
+
1713
+ deserializeNumber(expected, visit) {
1714
+ if (this.data.type === "num") return visit(this.data.value);
1715
+ throw this.invalid(expected);
1716
+ }
1717
+
1718
+ deserializeStr(expected, visit) {
1719
+ if (this.data.type === "str") return visit(this.data.value, this.data.borrowed);
1720
+ throw this.invalid(expected);
1721
+ }
1722
+
1723
+ visitSeq(visit) {
1724
+ const seq = new $JsonContentSeq(this.data.value, this.owned);
1725
+ const value = visit(seq);
1726
+ seq.end();
1727
+ return value;
1728
+ }
1729
+
1730
+ visitMap(visit) {
1731
+ const map = new $JsonContentMap(this.data.value, this.owned);
1732
+ const value = visit(map);
1733
+ map.end();
1734
+ return value;
1735
+ }
1736
+
1737
+ deserializeSeq(expected, visit) {
1738
+ if (this.data.type === "seq") return this.visitSeq(visit);
1739
+ throw this.invalid(expected);
1740
+ }
1741
+
1742
+ deserializeMap(expected, visitMap, visitSeq) {
1743
+ if (this.data.type === "seq" && visitSeq) return this.visitSeq(visitSeq);
1744
+ if (this.data.type === "map") return this.visitMap(visitMap);
1745
+ throw this.invalid(expected);
1746
+ }
1747
+
1748
+ deserializeAny(expected, visitor) {
1749
+ const { type, value } = this.data;
1750
+ if (type === "seq" && visitor.seq) return this.visitSeq(visitor.seq);
1751
+ if (type === "map" && visitor.map) return this.visitMap(visitor.map);
1752
+ const visit = { unit: visitor.unit, bool: visitor.bool, num: visitor.number, str: visitor.string }[type];
1753
+ if (visit) return visit(value);
1754
+ throw this.invalid(expected);
1755
+ }
1756
+
1757
+ bool() {
1758
+ if (this.data.type === "bool") return this.data.value;
1759
+ throw this.invalid("a boolean");
1760
+ }
1761
+
1762
+ unit(expected = "unit") {
1763
+ const { type, value } = this.data;
1764
+ // An owned one takes `{}` for a unit, as a newtype variant of `()`.
1765
+ if (type === "unit" || (this.owned && type === "map" && value.length === 0)) return undefined;
1766
+ throw this.invalid(expected);
1767
+ }
1768
+
1769
+ unitStruct(expected) {
1770
+ const { type, value } = this.data;
1771
+ if (type === "unit" || (this.owned && (type === "map" || type === "seq") && value.length === 0)) return undefined;
1772
+ throw this.invalid(expected);
1773
+ }
1774
+
1775
+ option(read) {
1776
+ return this.data.type === "unit" ? undefined : read(this);
1777
+ }
1778
+
1779
+ ignoreValue() {}
1780
+
1781
+ content() {
1782
+ return this.data;
1783
+ }
1784
+
1785
+ enum(enumName, variants, visit, other) {
1786
+ const { type, value } = this.data;
1787
+ let variant;
1788
+ let held;
1789
+ if (type === "map") {
1790
+ if (value.length !== 1) throw $jsonError("invalid value: map, expected map with a single key");
1791
+ [[variant, held]] = value;
1792
+ } else if (type === "str") {
1793
+ variant = this.data;
1794
+ } else {
1795
+ throw this.invalid("string or map");
1796
+ }
1797
+ const name = new $JsonContent(variant, this.owned).identifier(variants, other);
1798
+ return visit(name, new $JsonContentVariant(held, this.owned));
1799
+ }
1800
+
1801
+ // A variant's name, or its index among the variants.
1802
+ identifier(variants, other) {
1803
+ const { type, value } = this.data;
1804
+ if (type === "str") return $jsonVariantNamed(value, variants, other);
1805
+ if (type !== "num" || value.kind !== "u") throw this.invalid("variant identifier");
1806
+ if (value.value < variants.length) return $jsonName(variants[Number(value.value)]);
1807
+ if (other !== undefined) return other;
1808
+ throw $jsonError(`invalid value: integer \`${value.value}\`, expected variant index 0 <= i < ${variants.length}`);
1809
+ }
1810
+ }
1811
+
1812
+ // `SeqAccess`.
1813
+ export class $JsonSeq {
1814
+ constructor(reader) {
1815
+ this.reader = reader;
1816
+ this.first = true;
1817
+ }
1818
+
1819
+ // `has_next_element`.
1820
+ next() {
1821
+ const reader = this.reader;
1822
+ const peek = reader.parseWhitespace();
1823
+ if (peek === -1) throw reader.peekError("EOF while parsing a list");
1824
+ if (peek === 93) return false;
1825
+ if (this.first) {
1826
+ this.first = false;
1827
+ return true;
1828
+ }
1829
+ if (peek !== 44) throw reader.peekError("expected `,` or `]`");
1830
+ reader.index++;
1831
+ const c = reader.parseWhitespace();
1832
+ if (c === 93) throw reader.peekError("trailing comma");
1833
+ if (c === -1) throw reader.peekError("EOF while parsing a value");
1834
+ return true;
1835
+ }
1836
+
1837
+ value(read) {
1838
+ return read(this.reader);
1839
+ }
1840
+
1841
+ // The `i`th of `expected`'s items.
1842
+ element(read, i, expected, missing, defaults) {
1843
+ if (this.next()) return this.value(read);
1844
+ if (missing) return missing(defaults);
1845
+ throw $jsonError(`invalid length ${i}, expected ${expected}`);
1846
+ }
1847
+ }
1848
+
1849
+ // The items of a value already read.
1850
+ export class $JsonContentSeq {
1851
+ constructor(items, owned) {
1852
+ this.items = items;
1853
+ this.owned = owned;
1854
+ this.count = 0;
1855
+ }
1856
+
1857
+ next() {
1858
+ return this.count < this.items.length && ++this.count > 0;
1859
+ }
1860
+
1861
+ value(read) {
1862
+ return read(new $JsonContent(this.items[this.count - 1], this.owned));
1863
+ }
1864
+
1865
+ element(read, i, expected, missing, defaults) {
1866
+ return $JsonSeq.prototype.element.call(this, read, i, expected, missing, defaults);
1867
+ }
1868
+
1869
+ // Items left over: the length is wrong.
1870
+ end() {
1871
+ const length = this.items.length;
1872
+ if (this.count < length) {
1873
+ const count = this.count;
1874
+ throw $jsonError(`invalid length ${length}, expected ${count} element${count === 1 ? "" : "s"} in sequence`);
1875
+ }
1876
+ }
1877
+ }
1878
+
1879
+ // `MapAccess`.
1880
+ export class $JsonMap {
1881
+ constructor(reader) {
1882
+ this.reader = reader;
1883
+ this.first = true;
1884
+ }
1885
+
1886
+ // `has_next_key`.
1887
+ next() {
1888
+ const reader = this.reader;
1889
+ const peek = reader.parseWhitespace();
1890
+ if (peek === -1) throw reader.peekError("EOF while parsing an object");
1891
+ if (peek === 125) return false;
1892
+ if (this.first) {
1893
+ this.first = false;
1894
+ if (peek === 34) return true;
1895
+ throw reader.peekError("key must be a string");
1896
+ }
1897
+ if (peek !== 44) throw reader.peekError("expected `,` or `}`");
1898
+ reader.index++;
1899
+ const c = reader.parseWhitespace();
1900
+ if (c === 34) return true;
1901
+ throw reader.peekError(
1902
+ c === 125 ? "trailing comma" : c === -1 ? "EOF while parsing a value" : "key must be a string",
1903
+ );
1904
+ }
1905
+
1906
+ key() {
1907
+ return new $JsonKey(this.reader);
1908
+ }
1909
+
1910
+ value(read) {
1911
+ this.reader.parseObjectColon();
1912
+ return read(this.reader);
1913
+ }
1914
+ }
1915
+
1916
+ // The entries of a value already read.
1917
+ export class $JsonContentMap {
1918
+ constructor(entries, owned) {
1919
+ this.entries = entries;
1920
+ this.owned = owned;
1921
+ this.count = 0;
1922
+ }
1923
+
1924
+ next() {
1925
+ return this.count < this.entries.length && ++this.count > 0;
1926
+ }
1927
+
1928
+ key() {
1929
+ return new $JsonContentKey(this.entries[this.count - 1][0], this.owned);
1930
+ }
1931
+
1932
+ value(read) {
1933
+ return read(new $JsonContent(this.entries[this.count - 1][1], this.owned));
1934
+ }
1935
+
1936
+ end() {
1937
+ const length = this.entries.length;
1938
+ if (this.count < length) {
1939
+ const count = this.count;
1940
+ throw $jsonError(`invalid length ${length}, expected ${count} element${count === 1 ? "" : "s"} in map`);
1941
+ }
1942
+ }
1943
+ }
1944
+
1945
+ // `MapKey`: an object's key, from its opening quote. A number or a `bool`
1946
+ // is read from inside the quotes.
1947
+ export class $JsonKey {
1948
+ constructor(reader) {
1949
+ this.reader = reader;
1950
+ }
1951
+
1952
+ string() {
1953
+ this.reader.index++;
1954
+ return this.reader.parseStr();
1955
+ }
1956
+
1957
+ char() {
1958
+ return $jsonChar(this.string());
1959
+ }
1960
+
1961
+ ignore() {
1962
+ this.string();
1963
+ }
1964
+
1965
+ content() {
1966
+ const value = this.string();
1967
+ return { type: "str", value, borrowed: !this.reader.escaped };
1968
+ }
1969
+
1970
+ number(read) {
1971
+ const reader = this.reader;
1972
+ reader.index++;
1973
+ const c = reader.peek();
1974
+ if (!(c === 45 || (c >= 48 && c <= 57))) throw reader.error("invalid value: expected key to be a number in quotes");
1975
+ const value = read(reader);
1976
+ if (reader.peek() !== 34) throw reader.peekError('expected `"`');
1977
+ reader.index++;
1978
+ return value;
1979
+ }
1980
+
1981
+ bool() {
1982
+ const reader = this.reader;
1983
+ reader.index++;
1984
+ try {
1985
+ const c = reader.next();
1986
+ if (c === -1) throw reader.peekError("EOF while parsing a value");
1987
+ if (c === 116) {
1988
+ reader.parseIdent('rue"');
1989
+ return true;
1990
+ }
1991
+ if (c === 102) {
1992
+ reader.parseIdent('alse"');
1993
+ return false;
1994
+ }
1995
+ throw $jsonError(`invalid type: string ${$debugStr(reader.parseStr())}, expected a boolean`);
1996
+ } catch (e) {
1997
+ throw reader.fixPosition(e);
1998
+ }
1999
+ }
2000
+ }
2001
+
2002
+ // A key already read: it's read as any other value is, so a number in
2003
+ // quotes isn't a number, as in serde.
2004
+ export class $JsonContentKey {
2005
+ constructor(key, owned) {
2006
+ this.key = new $JsonContent(key, owned);
2007
+ }
2008
+
2009
+ string() {
2010
+ return this.key.string();
2011
+ }
2012
+
2013
+ char() {
2014
+ return this.key.char();
2015
+ }
2016
+
2017
+ bool() {
2018
+ return this.key.bool();
2019
+ }
2020
+
2021
+ ignore() {}
2022
+
2023
+ content() {
2024
+ return this.key.content();
2025
+ }
2026
+
2027
+ number(read) {
2028
+ return read(this.key);
2029
+ }
2030
+ }
2031
+
2032
+ // `VariantAccess` of `{"Name": ..}`, or of `"Name"` (`unit`), which holds
2033
+ // nothing.
2034
+ export class $JsonVariant {
2035
+ constructor(reader, unit) {
2036
+ this.reader = reader;
2037
+ this.isUnit = unit;
2038
+ }
2039
+
2040
+ unit() {
2041
+ if (!this.isUnit) this.reader.unit();
2042
+ }
2043
+
2044
+ newtype(read) {
2045
+ if (this.isUnit) throw $jsonError("invalid type: unit variant, expected newtype variant");
2046
+ return read(this.reader);
2047
+ }
2048
+
2049
+ tuple(expected, fields, build, options) {
2050
+ if (this.isUnit) throw $jsonError("invalid type: unit variant, expected tuple variant");
2051
+ return this.reader.tupleStruct(expected, fields, build, options);
2052
+ }
2053
+
2054
+ // With a flattened field, serde reads it as a newtype variant of a map.
2055
+ struct(expected, fields, build, options) {
2056
+ if (this.isUnit) {
2057
+ throw $jsonError(`invalid type: unit variant, expected ${options?.flatten ? "newtype" : "struct"} variant`);
2058
+ }
2059
+ return this.reader.struct(expected, fields, build, options);
2060
+ }
2061
+ }
2062
+
2063
+ // The same, of a value already read: what a variant holds, if anything.
2064
+ export class $JsonContentVariant {
2065
+ constructor(held, owned) {
2066
+ this.held = held;
2067
+ this.owned = owned;
2068
+ }
2069
+
2070
+ reader(kind, types) {
2071
+ if (this.held === undefined) throw $jsonError(`invalid type: unit variant, expected ${kind}`);
2072
+ if (types && !types.includes(this.held.type)) {
2073
+ throw $jsonError(`invalid type: ${$jsonUnexpectedContent(this.held)}, expected ${kind}`);
2074
+ }
2075
+ return new $JsonContent(this.held, this.owned);
2076
+ }
2077
+
2078
+ unit() {
2079
+ if (this.held !== undefined) new $JsonContent(this.held, this.owned).unit();
2080
+ }
2081
+
2082
+ newtype(read) {
2083
+ return read(this.reader("newtype variant"));
2084
+ }
2085
+
2086
+ tuple(expected, fields, build, options) {
2087
+ return this.reader("tuple variant", ["seq"]).tupleStruct(expected, fields, build, options);
2088
+ }
2089
+
2090
+ struct(expected, fields, build, options) {
2091
+ const reader = options?.flatten ? this.reader("newtype variant") : this.reader("struct variant", ["map", "seq"]);
2092
+ return reader.struct(expected, fields, build, options);
2093
+ }
2094
+ }
2095
+
2096
+ // A flattened field (serde's `FlatMapDeserializer`): what's left of its
2097
+ // struct's object. A struct takes the entries it has fields for, a map or an
2098
+ // untagged or internally tagged enum sees every one left, and an enum takes
2099
+ // the first that names a variant. Anything else can't be flattened.
2100
+ export class $JsonFlat extends $JsonDecoder {
2101
+ constructor(entries) {
2102
+ super();
2103
+ this.entries = entries;
2104
+ }
2105
+
2106
+ other() {
2107
+ return $jsonError("can only flatten structs and maps");
2108
+ }
2109
+
2110
+ deserializeNumber() {
2111
+ throw this.other();
2112
+ }
2113
+
2114
+ deserializeStr() {
2115
+ throw this.other();
2116
+ }
2117
+
2118
+ deserializeSeq() {
2119
+ throw this.other();
2120
+ }
2121
+
2122
+ bool() {
2123
+ throw this.other();
2124
+ }
2125
+
2126
+ identifier() {
2127
+ throw this.other();
2128
+ }
2129
+
2130
+ deserializeMap(expected, visitMap) {
2131
+ return visitMap(new $JsonFlatMap(this.entries));
2132
+ }
2133
+
2134
+ deserializeStruct(expected, names, visitMap) {
2135
+ return visitMap(new $JsonFlatStruct(this.entries, names));
2136
+ }
2137
+
2138
+ deserializeAny(expected, visitor) {
2139
+ return this.deserializeMap(expected, (map) => {
2140
+ if (!visitor.map) throw $jsonError(`invalid type: map, expected ${expected}`);
2141
+ return visitor.map(map);
2142
+ });
2143
+ }
2144
+
2145
+ unit() {
2146
+ return undefined;
2147
+ }
2148
+
2149
+ unitStruct() {
2150
+ return undefined;
2151
+ }
2152
+
2153
+ ignoreValue() {}
2154
+
2155
+ // An `Option`: `None` when what it holds can't be read from what's left.
2156
+ option(read) {
2157
+ try {
2158
+ return read(this);
2159
+ } catch (e) {
2160
+ if (!(e instanceof $JsonError)) throw e;
2161
+ return undefined;
2162
+ }
2163
+ }
2164
+
2165
+ content() {
2166
+ return { type: "map", value: this.entries.filter(Boolean) };
2167
+ }
2168
+
2169
+ enum(enumName, variants, visit, other) {
2170
+ const names = variants.flatMap((names) => names);
2171
+ const i = this.entries.findIndex((entry) => entry && entry[0].type === "str" && names.includes(entry[0].value));
2172
+ if (i < 0) throw $jsonError(`no variant of enum ${enumName} found in flattened data`);
2173
+ const entry = this.entries[i];
2174
+ this.entries[i] = null;
2175
+ return new $JsonContent({ type: "map", value: [entry] }, true).enum(enumName, variants, visit, other);
2176
+ }
2177
+ }
2178
+
2179
+ // `FlatStructAccess`: the entries a struct has fields for, taken.
2180
+ export class $JsonFlatStruct {
2181
+ constructor(entries, names) {
2182
+ this.entries = entries;
2183
+ this.names = names;
2184
+ this.index = 0;
2185
+ }
2186
+
2187
+ next() {
2188
+ while (this.index < this.entries.length) {
2189
+ const i = this.index++;
2190
+ const entry = this.entries[i];
2191
+ if (entry && entry[0].type === "str" && this.names.includes(entry[0].value)) {
2192
+ this.entries[i] = null;
2193
+ this.entry = entry;
2194
+ return true;
2195
+ }
2196
+ }
2197
+ return false;
2198
+ }
2199
+
2200
+ key() {
2201
+ return new $JsonContentKey(this.entry[0], true);
2202
+ }
2203
+
2204
+ value(read) {
2205
+ return read(new $JsonContent(this.entry[1], true));
2206
+ }
2207
+ }
2208
+
2209
+ // `FlatMapAccess`: every entry left, seen but left for the fields after.
2210
+ export class $JsonFlatMap {
2211
+ constructor(entries) {
2212
+ this.entries = entries;
2213
+ this.index = 0;
2214
+ }
2215
+
2216
+ next() {
2217
+ while (this.index < this.entries.length) {
2218
+ const entry = this.entries[this.index++];
2219
+ if (entry) {
2220
+ this.entry = entry;
2221
+ return true;
2222
+ }
2223
+ }
2224
+ return false;
2225
+ }
2226
+
2227
+ key() {
2228
+ return new $JsonContentKey(this.entry[0], false);
2229
+ }
2230
+
2231
+ value(read) {
2232
+ return read(new $JsonContent(this.entry[1], false));
2233
+ }
2234
+ }
2235
+
2236
+ // A `serde_json::Value` read as a deserializer (ADR 0083), for
2237
+ // `serde_json::from_value`: its `impl Deserializer for Value`.
2238
+ export class $JsonValueReader extends $JsonDecoder {
2239
+ constructor(value) {
2240
+ super();
2241
+ this.value = value;
2242
+ }
2243
+
2244
+ // serde_json's `Value::unexpected`.
2245
+ unexpected() {
2246
+ const value = this.value;
2247
+ if (value === "Null") return "null";
2248
+ const { TAG: tag, _0: inner } = value;
2249
+ if (tag === "Bool") return `boolean \`${inner}\``;
2250
+ if (tag === "Number") return $jsonUnexpectedNumber(inner);
2251
+ if (tag === "String") return `string ${$debugStr(inner)}`;
2252
+ return tag === "Array" ? "sequence" : "map";
2253
+ }
2254
+
2255
+ invalid(expected) {
2256
+ return $jsonError(`invalid type: ${this.unexpected()}, expected ${expected}`);
2257
+ }
2258
+
2259
+ deserializeNumber(expected, visit) {
2260
+ if (this.value.TAG === "Number") return visit(this.value._0);
2261
+ throw this.invalid(expected);
2262
+ }
2263
+
2264
+ // A string of a `Value` is its own, so a `&str` can't borrow it.
2265
+ deserializeStr(expected, visit) {
2266
+ if (this.value.TAG === "String") return visit(this.value._0, false);
2267
+ throw this.invalid(expected);
2268
+ }
2269
+
2270
+ visitArray(visit) {
2271
+ const items = this.value._0;
2272
+ const seq = new $JsonValueSeq(items);
2273
+ const value = visit(seq);
2274
+ if (seq.count < items.length) throw $jsonError(`invalid length ${items.length}, expected fewer elements in array`);
2275
+ return value;
2276
+ }
2277
+
2278
+ visitObject(visit) {
2279
+ const entries = $sortedEntries(this.value._0, $cmp);
2280
+ const map = new $JsonValueMap(entries);
2281
+ const value = visit(map);
2282
+ if (map.count < entries.length) throw $jsonError(`invalid length ${entries.length}, expected fewer elements in map`);
2283
+ return value;
2284
+ }
2285
+
2286
+ deserializeSeq(expected, visit) {
2287
+ if (this.value.TAG === "Array") return this.visitArray(visit);
2288
+ throw this.invalid(expected);
2289
+ }
2290
+
2291
+ deserializeMap(expected, visitMap, visitSeq) {
2292
+ if (this.value.TAG === "Array" && visitSeq) return this.visitArray(visitSeq);
2293
+ if (this.value.TAG === "Object") return this.visitObject(visitMap);
2294
+ throw this.invalid(expected);
2295
+ }
2296
+
2297
+ deserializeAny(expected, visitor) {
2298
+ const value = this.value;
2299
+ if (value === "Null") {
2300
+ if (visitor.unit) return visitor.unit();
2301
+ throw this.invalid(expected);
2302
+ }
2303
+ const { TAG: tag, _0: inner } = value;
2304
+ if (tag === "Array") {
2305
+ return this.visitArray((seq) => {
2306
+ if (!visitor.seq) throw this.invalid(expected);
2307
+ return visitor.seq(seq);
2308
+ });
2309
+ }
2310
+ if (tag === "Object") {
2311
+ return this.visitObject((map) => {
2312
+ if (!visitor.map) throw this.invalid(expected);
2313
+ return visitor.map(map);
2314
+ });
2315
+ }
2316
+ const visit = { Bool: visitor.bool, Number: visitor.number, String: visitor.string }[tag];
2317
+ if (visit) return visit(inner, false);
2318
+ throw this.invalid(expected);
2319
+ }
2320
+
2321
+ bool() {
2322
+ if (this.value.TAG === "Bool") return this.value._0;
2323
+ throw this.invalid("a boolean");
2324
+ }
2325
+
2326
+ unit(expected = "unit") {
2327
+ if (this.value === "Null") return undefined;
2328
+ throw this.invalid(expected);
2329
+ }
2330
+
2331
+ unitStruct(expected) {
2332
+ return this.unit(expected);
2333
+ }
2334
+
2335
+ option(read) {
2336
+ return this.value === "Null" ? undefined : read(this);
2337
+ }
2338
+
2339
+ ignoreValue() {}
2340
+
2341
+ // serde's `ContentVisitor` of it: a string is an owned one.
2342
+ content() {
2343
+ return $jsonValueContent(this.value);
2344
+ }
2345
+
2346
+ enum(enumName, variants, visit, other) {
2347
+ const value = this.value;
2348
+ let name;
2349
+ let held;
2350
+ if (value.TAG === "Object") {
2351
+ if (value._0.size !== 1) throw $jsonError("invalid value: map, expected map with a single key");
2352
+ [[name, held]] = value._0;
2353
+ } else if (value.TAG === "String") {
2354
+ name = value._0;
2355
+ } else {
2356
+ throw this.invalid("string or map");
2357
+ }
2358
+ return visit($jsonVariantNamed(name, variants, other), new $JsonValueVariant(held));
2359
+ }
2360
+
2361
+ identifier(variants, other) {
2362
+ return this.deserializeStr("variant identifier", (name) => $jsonVariantNamed(name, variants, other));
2363
+ }
2364
+ }
2365
+
2366
+ export function $jsonValueContent(value) {
2367
+ if (value === "Null") return { type: "unit" };
2368
+ const { TAG: tag, _0: inner } = value;
2369
+ if (tag === "Bool") return { type: "bool", value: inner };
2370
+ if (tag === "Number") return { type: "num", value: inner };
2371
+ if (tag === "String") return { type: "str", value: inner, borrowed: false };
2372
+ if (tag === "Array") return { type: "seq", value: inner.map($jsonValueContent) };
2373
+ const entries = $sortedEntries(inner, $cmp).map(([key, item]) => [
2374
+ { type: "str", value: key, borrowed: false },
2375
+ $jsonValueContent(item),
2376
+ ]);
2377
+ return { type: "map", value: entries };
2378
+ }
2379
+
2380
+ export class $JsonValueSeq {
2381
+ constructor(items) {
2382
+ this.items = items;
2383
+ this.count = 0;
2384
+ }
2385
+
2386
+ next() {
2387
+ return this.count < this.items.length && ++this.count > 0;
2388
+ }
2389
+
2390
+ value(read) {
2391
+ return read(new $JsonValueReader(this.items[this.count - 1]));
2392
+ }
2393
+
2394
+ element(read, i, expected, missing, defaults) {
2395
+ return $JsonSeq.prototype.element.call(this, read, i, expected, missing, defaults);
2396
+ }
2397
+ }
2398
+
2399
+ export class $JsonValueMap {
2400
+ constructor(entries) {
2401
+ this.entries = entries;
2402
+ this.count = 0;
2403
+ }
2404
+
2405
+ next() {
2406
+ return this.count < this.entries.length && ++this.count > 0;
2407
+ }
2408
+
2409
+ key() {
2410
+ return new $JsonValueKey(this.entries[this.count - 1][0]);
2411
+ }
2412
+
2413
+ value(read) {
2414
+ return read(new $JsonValueReader(this.entries[this.count - 1][1]));
2415
+ }
2416
+ }
2417
+
2418
+ // serde_json's `MapKeyDeserializer`: an object's key, a number read from it
2419
+ // as JSON text would be.
2420
+ export class $JsonValueKey {
2421
+ constructor(key) {
2422
+ this.key = key;
2423
+ }
2424
+
2425
+ string() {
2426
+ return this.key;
2427
+ }
2428
+
2429
+ char() {
2430
+ return $jsonChar(this.key);
2431
+ }
2432
+
2433
+ ignore() {}
2434
+
2435
+ content() {
2436
+ return { type: "str", value: this.key, borrowed: false };
2437
+ }
2438
+
2439
+ number(read) {
2440
+ const json = new $JsonReader(this.key);
2441
+ const c = json.peek();
2442
+ if (!(c === 45 || (c >= 48 && c <= 57))) throw $jsonError("invalid value: expected key to be a number in quotes");
2443
+ const value = read(json);
2444
+ if (json.peek() !== -1) throw $jsonError("invalid value: expected key to be a number in quotes");
2445
+ return value;
2446
+ }
2447
+
2448
+ bool() {
2449
+ if (this.key === "true" || this.key === "false") return this.key === "true";
2450
+ throw $jsonError(`invalid type: string ${$debugStr(this.key)}, expected a boolean`);
2451
+ }
2452
+ }
2453
+
2454
+ // `VariantAccess` of a `Value`'s variant: what it holds, if anything.
2455
+ export class $JsonValueVariant {
2456
+ constructor(held) {
2457
+ this.held = held;
2458
+ }
2459
+
2460
+ reader(kind, tag) {
2461
+ if (this.held === undefined) throw $jsonError(`invalid type: unit variant, expected ${kind}`);
2462
+ const reader = new $JsonValueReader(this.held);
2463
+ if (tag && this.held.TAG !== tag) throw reader.invalid(kind);
2464
+ return reader;
2465
+ }
2466
+
2467
+ unit() {
2468
+ if (this.held !== undefined) new $JsonValueReader(this.held).unit();
2469
+ }
2470
+
2471
+ newtype(read) {
2472
+ return read(this.reader("newtype variant"));
2473
+ }
2474
+
2475
+ tuple(expected, fields, build, options) {
2476
+ const reader = this.reader("tuple variant", "Array");
2477
+ // An empty array is a unit, which a tuple variant isn't.
2478
+ if (this.held._0.length === 0) throw $jsonError(`invalid type: null, expected ${options?.expecting ?? expected}`);
2479
+ return reader.tupleStruct(expected, fields, build, options);
2480
+ }
2481
+
2482
+ struct(expected, fields, build, options) {
2483
+ if (options?.flatten) return this.reader("newtype variant").struct(expected, fields, build, options);
2484
+ return this.reader("struct variant", "Object").struct(expected, fields, build, options);
2485
+ }
2486
+ }
2487
+
2488
+ // `serde_json::from_value`: a `Result` of what `read` reads of `value`.
2489
+ export function $fromJsonValue(value, read) {
2490
+ try {
2491
+ return { TAG: "Ok", _0: read(new $JsonValueReader(value)) };
2492
+ } catch (e) {
2493
+ if (e instanceof $JsonError) return { TAG: "Err", _0: { message: e.message, line: e.line, column: e.column } };
2494
+ throw e;
2495
+ }
2496
+ }
2497
+
2498
+ // serde's `missing_field`: what a field that isn't there reads as, which is
2499
+ // `None` for an `Option`, and otherwise an error. An adjacently tagged
2500
+ // enum's content that isn't there is read so too, and is nothing for a
2501
+ // unit variant.
2502
+ export class $JsonMissing {
2503
+ constructor(name) {
2504
+ this.name = name;
2505
+ }
2506
+
2507
+ option() {
2508
+ return undefined;
2509
+ }
2510
+
2511
+ untaggedUnit() {
2512
+ return undefined;
2513
+ }
2514
+ }
2515
+ for (const method of [
2516
+ "bool", "int", "f64", "string", "char", "borrowedStr", "unit", "unitStruct", "vec", "tuple", "array", "map",
2517
+ "struct", "untaggedStruct", "tupleStruct", "enum", "taggedUnit", "internallyTagged",
2518
+ "adjacentlyTagged", "untagged",
2519
+ ]) {
2520
+ $JsonMissing.prototype[method] = function () {
2521
+ throw $jsonError(`missing field \`${this.name}\``);
2522
+ };
2523
+ }
2524
+
2525
+ export const $JSON_UTF8 = new TextDecoder();
2526
+ export const $JSON_POW10 = Array.from({ length: 309 }, (_, i) => Number(`1e${i}`));
2527
+
2528
+ // `significand * 10 + digit`, a BigInt once it's past 2^53.
2529
+ export function $jsonGrow(significand, digit) {
2530
+ if (typeof significand === "number") {
2531
+ const grown = significand * 10 + digit;
2532
+ if (grown <= Number.MAX_SAFE_INTEGER) return grown;
2533
+ }
2534
+ return BigInt(significand) * 10n + BigInt(digit);
2535
+ }
2536
+
2537
+ export function $jsonHexDigit(c) {
2538
+ if (c >= 48 && c <= 57) return c - 48;
2539
+ if (c >= 65 && c <= 70) return c - 55;
2540
+ if (c >= 97 && c <= 102) return c - 87;
2541
+ return -1;
2542
+ }
2543
+
2544
+ // serde's `Unexpected` of a number, a float as serde_json writes one.
2545
+ export function $jsonUnexpectedNumber(n) {
2546
+ return n.kind === "f" ? `floating point \`${$jsonNumber(n.value)}\`` : `integer \`${n.value}\``;
2547
+ }
2548
+
2549
+ export function $jsonChar(s) {
2550
+ if ([...s].length === 1) return s;
2551
+ throw $jsonError(`invalid value: string ${$debugStr(s)}, expected a character`);
2552
+ }
2553
+
2554
+ // serde's `Unexpected` of a value already read.
2555
+ export function $jsonUnexpectedContent({ type, value }) {
2556
+ if (type === "unit") return "null";
2557
+ if (type === "bool") return `boolean \`${value}\``;
2558
+ if (type === "num") return $jsonUnexpectedNumber(value);
2559
+ if (type === "str") return `string ${$debugStr(value)}`;
2560
+ return type === "seq" ? "sequence" : "map";
2561
+ }
2562
+
2563
+ // The variant a name names, or `other`'s, as a derive's variant visitor finds it.
2564
+ export function $jsonVariantNamed(name, variants, other) {
2565
+ for (const names of variants) {
2566
+ if (typeof names === "string" ? names === name : names.includes(name)) return $jsonName(names);
2567
+ }
2568
+ if (other !== undefined) return other;
2569
+ throw variants.length === 0
2570
+ ? $jsonError(`unknown variant \`${name}\`, there are no variants`)
2571
+ : $jsonError(`unknown variant \`${name}\`, expected ${$jsonOneOf(variants)}`);
2572
+ }
2573
+
2574
+ export function $jsonName(names) {
2575
+ return typeof names === "string" ? names : names[0];
2576
+ }
2577
+
2578
+ // The field a key names, or -1 to skip its value.
2579
+ export function $jsonField(key, fields, deny) {
2580
+ const i = fields.findIndex(([names]) => (typeof names === "string" ? names === key : names.includes(key)));
2581
+ if (i >= 0 || !deny) return i;
2582
+ throw fields.length === 0
2583
+ ? $jsonError(`unknown field \`${key}\`, there are no fields`)
2584
+ : $jsonError(`unknown field \`${key}\`, expected ${$jsonOneOf(fields.map(([names]) => names))}`);
2585
+ }
2586
+
2587
+ // serde's `OneOf`, of each name and its aliases, which serde keeps sorted.
2588
+ export function $jsonOneOf(entries) {
2589
+ const byCodePoint = (a, b) => {
2590
+ const [x, y] = [[...a], [...b]];
2591
+ for (let i = 0; i < Math.min(x.length, y.length); i++) {
2592
+ const d = x[i].codePointAt(0) - y[i].codePointAt(0);
2593
+ if (d !== 0) return d;
2594
+ }
2595
+ return x.length - y.length;
2596
+ };
2597
+ const names = entries.flatMap((names) => (typeof names === "string" ? [names] : [...names].sort(byCodePoint)));
2598
+ const quoted = names.map((name) => `\`${name}\``);
2599
+ if (quoted.length === 1) return quoted[0];
2600
+ if (quoted.length === 2) return `${quoted[0]} or ${quoted[1]}`;
2601
+ return `one of ${quoted.join(", ")}`;
2602
+ }
2603
+
2604
+ // What the crate reads with: `$json.u32`, `$json.option($json.string)`.
2605
+ export const $json = {
2606
+ bool: (json) => json.bool(),
2607
+ u8: (json) => json.int("u8", 0, 255),
2608
+ u16: (json) => json.int("u16", 0, 65535),
2609
+ u32: (json) => json.int("u32", 0, 4294967295),
2610
+ usize: (json) => json.int("usize", 0, 4294967295),
2611
+ i8: (json) => json.int("i8", -128, 127),
2612
+ i16: (json) => json.int("i16", -32768, 32767),
2613
+ i32: (json) => json.int("i32", -2147483648, 2147483647),
2614
+ isize: (json) => json.int("isize", -2147483648, 2147483647),
2615
+ u64: (json) => json.int("u64", 0n, 18446744073709551615n),
2616
+ i64: (json) => json.int("i64", -9223372036854775808n, 9223372036854775807n),
2617
+ f64: (json) => json.f64(),
2618
+ string: (json) => json.string(),
2619
+ str: (json) => json.borrowedStr(),
2620
+ // serde_json's `Value` (ADR 0083), from whatever's there, and its `Number`.
2621
+ value: (json) => json.deserializeAny("any valid JSON value", $JSON_VALUE),
2622
+ number: (json) =>
2623
+ json.deserializeAny("a JSON number", {
2624
+ number: (n) => {
2625
+ if (n.kind === "f" && !Number.isFinite(n.value)) throw $jsonError("not a JSON number");
2626
+ return n;
2627
+ },
2628
+ }),
2629
+ char: (json) => json.char(),
2630
+ unit: (json) => json.unit(),
2631
+ option: (read) => (json) => json.option(read),
2632
+ // A generic `T` in an `Option`, boxed when it looks like `None` (ADR 0051).
2633
+ some: (read) => (json) => $some(read(json)),
2634
+ // A generic type's reader, given its type arguments' readers (ADR 0080).
2635
+ with:
2636
+ (deserialize, ...readers) =>
2637
+ (json) =>
2638
+ deserialize(json, ...readers),
2639
+ vec: (read) => (json) => json.vec(read),
2640
+ set: (read) => (json) => new Set(json.vec(read)),
2641
+ map: (readKey, read) => (json) => json.map(readKey, read),
2642
+ tuple: (...reads) => (json) => json.tuple(reads),
2643
+ // `#[serde(try_from = "T")]`: the value of a `TryFrom`'s `Ok`, and of an
2644
+ // `Err`, serde's `Error::custom` of its `display`.
2645
+ tried: (result, display) => {
2646
+ if (result.TAG === "Err") throw $jsonError(display(result._0));
2647
+ return result._0;
2648
+ },
2649
+ // serde's impl for `Result`: `{"Ok": ..}` or `{"Err": ..}`.
2650
+ result: (ok, err) => (json) =>
2651
+ json.enum("Result", ["Ok", "Err"], (variant, content) => ({
2652
+ TAG: variant,
2653
+ _0: content.newtype(variant === "Ok" ? ok : err),
2654
+ })),
2655
+ array: (length, read) => (json) => json.array(length, read),
2656
+ // An object's keys.
2657
+ key: {
2658
+ string: (key) => key.string(),
2659
+ char: (key) => key.char(),
2660
+ bool: (key) => key.bool(),
2661
+ number: (read) => (key) => key.number(read),
2662
+ },
2663
+ };
2664
+
2665
+ // serde_json's `ValueVisitor`: a `Value` of each kind.
2666
+ export const $JSON_VALUE = {
2667
+ unit: () => "Null",
2668
+ bool: (b) => ({ TAG: "Bool", _0: b }),
2669
+ number: (n) => ({ TAG: "Number", _0: n }),
2670
+ string: (s) => ({ TAG: "String", _0: s }),
2671
+ seq: (seq) => {
2672
+ const items = [];
2673
+ while (seq.next()) items.push(seq.value($json.value));
2674
+ return { TAG: "Array", _0: items };
2675
+ },
2676
+ map: (map) => {
2677
+ const entries = new Map();
2678
+ while (map.next()) {
2679
+ const key = map.key().string();
2680
+ entries.set(key, map.value($json.value));
2681
+ }
2682
+ return { TAG: "Object", _0: entries };
2683
+ },
2684
+ };
2685
+
2686
+ // `serde_json::from_str`: a `Result` of what `read` reads, which must be
2687
+ // all there is.
2688
+ export function $fromJson(text, read) {
2689
+ const json = new $JsonReader(text);
2690
+ try {
2691
+ const value = read(json);
2692
+ json.end();
2693
+ return { TAG: "Ok", _0: value };
2694
+ } catch (e) {
2695
+ if (e instanceof $JsonError) return { TAG: "Err", _0: { message: e.message, line: e.line, column: e.column } };
2696
+ throw e;
2697
+ }
2698
+ }
2699
+
2700
+ // serde_json's `Value` (ADR 0083): `"Null"`, or `{ TAG, _0 }` of `Bool`,
2701
+ // `Number`, `String`, `Array` or `Object`, whose `Map` is a JS `Map`. A
2702
+ // `Number` is `{ kind, value }`: `"u"` and `"i"` are integers (a BigInt past
2703
+ // 2^53), `"f"` a finite float.
2704
+
2705
+ // `Number::from` of an integer, and `Value::from` of an `f64`, which is
2706
+ // `Null` unless it's finite.
2707
+ export function $jsonInt(n) {
2708
+ return { kind: n < 0 ? "i" : "u", value: n };
2709
+ }
2710
+ export function $jsonFloat(x) {
2711
+ return Number.isFinite(x) ? { TAG: "Number", _0: { kind: "f", value: x } } : "Null";
2712
+ }
2713
+ // `Number::from_f64`: `None` unless it's finite.
2714
+ export function $jsonNumberOfF64(x) {
2715
+ return Number.isFinite(x) ? { kind: "f", value: x } : undefined;
2716
+ }
2717
+ // `Value::from` of an `Option`: `Null`, or what it holds, converted.
2718
+ export function $jsonOption(o, convert) {
2719
+ return o == null ? "Null" : convert(o);
2720
+ }
2721
+
2722
+ export function $jsonNumberWrite(n, json) {
2723
+ if (n.kind === "f") json.number(n.value);
2724
+ else json.int(n.value);
2725
+ }
2726
+
2727
+ // serde_json's `Serialize` for `Value`: an object's keys in the order its
2728
+ // `BTreeMap` keeps them.
2729
+ export function $jsonValueWrite(value, json) {
2730
+ if (value === "Null") return json.null();
2731
+ const { TAG: tag, _0: inner } = value;
2732
+ if (tag === "Bool") return json.bool(inner);
2733
+ if (tag === "Number") return $jsonNumberWrite(inner, json);
2734
+ if (tag === "String") return json.string(inner);
2735
+ if (tag === "Array") {
2736
+ json.beginArray();
2737
+ for (const item of inner) {
2738
+ json.element();
2739
+ $jsonValueWrite(item, json);
2740
+ }
2741
+ return json.endArray();
2742
+ }
2743
+ json.beginObject();
2744
+ for (const [key, item] of $sortedEntries(inner, $cmp)) {
2745
+ json.key(key);
2746
+ $jsonValueWrite(item, json);
2747
+ }
2748
+ json.endObject();
2749
+ }
2750
+
2751
+ // `clone()`: a copy of each array and map, which change in place; a
2752
+ // string or a number can't.
2753
+ export function $jsonValueClone(value) {
2754
+ if (value.TAG === "Array") return { TAG: "Array", _0: value._0.map($jsonValueClone) };
2755
+ if (value.TAG === "Object") return { TAG: "Object", _0: $jsonMapClone(value._0) };
2756
+ return value;
2757
+ }
2758
+ export function $jsonMapClone(map) {
2759
+ return new Map(Array.from(map, ([key, item]) => [key, $jsonValueClone(item)]));
2760
+ }
2761
+
2762
+ // `{}` of a `Value`, its JSON, and with `{:#}`, its pretty JSON.
2763
+ export function $jsonValueText(value, pretty) {
2764
+ return $toJson(value, $jsonValueWrite, pretty)._0;
2765
+ }
2766
+ export function $jsonNumberText(n) {
2767
+ return n.kind === "f" ? $jsonNumber(n.value) : String(n.value);
2768
+ }
2769
+
2770
+ // serde_json's `Debug`: `Null`, `Bool(true)`, `Number(1)`, `String("a")`,
2771
+ // `Array [..]` and `Object {..}`.
2772
+ export function $debugJsonValue(value) {
2773
+ if (value === "Null") return "Null";
2774
+ const { TAG: tag, _0: inner } = value;
2775
+ if (tag === "Bool") return `Bool(${inner})`;
2776
+ if (tag === "Number") return $debugJsonNumber(inner);
2777
+ if (tag === "String") return `String(${$debugStr(inner)})`;
2778
+ if (tag === "Array") return `Array [${inner.map($debugJsonValue).join(", ")}]`;
2779
+ const entries = $sortedEntries(inner, $cmp).map(([key, item]) => `${$debugStr(key)}: ${$debugJsonValue(item)}`);
2780
+ return `Object {${entries.join(", ")}}`;
2781
+ }
2782
+ export function $debugJsonNumber(n) {
2783
+ return `Number(${$jsonNumberText(n)})`;
2784
+ }
2785
+
2786
+ // `as_bool`, `as_str`, `as_array`, `as_object`: what the variant `tag`
2787
+ // holds, if it's that one.
2788
+ export function $jsonValueAs(value, tag) {
2789
+ return value.TAG === tag ? value._0 : undefined;
2790
+ }
2791
+ export function $jsonValueF64(value) {
2792
+ return value.TAG === "Number" ? $jsonNumberF64(value._0) : undefined;
2793
+ }
2794
+ export function $jsonNumberF64(n) {
2795
+ return Number(n.value);
2796
+ }
2797
+ // `as_u64()` and `as_i64()`: the integer, a BigInt, if it's of that kind
2798
+ // and fits.
2799
+ export function $jsonNumberInt(n, kind) {
2800
+ const fits = kind === "u64" ? n.kind === "u" : $jsonNumberIsI64(n);
2801
+ return fits ? BigInt(n.value) : undefined;
2802
+ }
2803
+ export function $jsonValueInt(value, kind) {
2804
+ return value.TAG === "Number" ? $jsonNumberInt(value._0, kind) : undefined;
2805
+ }
2806
+ export function $jsonNumberIsI64(n) {
2807
+ return n.kind === "i" || (n.kind === "u" && n.value <= 9223372036854775807n);
2808
+ }
2809
+ // `is_f64`, `is_u64` and `is_i64` of a `Value`.
2810
+ export function $jsonValueIs(value, kind) {
2811
+ if (value.TAG !== "Number") return false;
2812
+ if (kind === "i64") return $jsonNumberIsI64(value._0);
2813
+ return value._0.kind === kind[0];
2814
+ }
2815
+
2816
+ // `get(key)` of an object, or `get(i)` of an array, and `value[key]`, which is
2817
+ // `Null` for what isn't there.
2818
+ export function $jsonGet(value, key) {
2819
+ if (typeof key === "string") return value.TAG === "Object" ? value._0.get(key) : undefined;
2820
+ return value.TAG === "Array" ? value._0[key] : undefined;
2821
+ }
2822
+ export function $jsonIndex(value, key) {
2823
+ return $jsonGet(value, key) ?? "Null";
2824
+ }
2825
+
2826
+ // serde_json's `PartialEq` of a `Value` and a `String`, a `bool` or a
2827
+ // number: `as_str()`, `as_bool()`, `as_f64()`, `as_i64()` or `as_u64()`
2828
+ // is it.
2829
+ export function $jsonValueEq(value, other, kind) {
2830
+ if (kind === "String" || kind === "Bool") return value.TAG === kind && value._0 === other;
2831
+ if (value.TAG !== "Number") return false;
2832
+ const n = value._0;
2833
+ if (kind === "f64") return Number(n.value) === other;
2834
+ if (kind === "i64") return $jsonNumberIsI64(n) && n.value == other;
2835
+ return n.kind === "u" && n.value == other;
2836
+ }
2837
+
2838
+ // `serde_json::to_value`: a `Value` of what `write` writes, serde_json's
2839
+ // value serializer. A `NaN` is `Null`, and a map's keys are strings.
2840
+ export function $toJsonValue(value, write) {
2841
+ const stack = [];
2842
+ let root;
2843
+ const put = (v) => {
2844
+ const top = stack[stack.length - 1];
2845
+ if (!top) root = v;
2846
+ else if (top.items) top.items.push(v);
2847
+ else top.entries.set(top.key, v);
2848
+ };
2849
+ const string = (s) => put({ TAG: "String", _0: s });
2850
+ const open = () => stack.push({ items: [] });
2851
+ const builder = {
2852
+ null: () => put("Null"),
2853
+ bool: (b) => put({ TAG: "Bool", _0: b }),
2854
+ int: (n) => put({ TAG: "Number", _0: $jsonInt(n) }),
2855
+ number: (x) => put($jsonFloat(x)),
2856
+ char: string,
2857
+ string,
2858
+ variant: string,
2859
+ beginArray: open,
2860
+ beginTuple: open,
2861
+ beginTupleStruct: open,
2862
+ element() {},
2863
+ endArray: () => put({ TAG: "Array", _0: stack.pop().items }),
2864
+ beginObject: () => stack.push({ entries: new Map() }),
2865
+ key(k) {
2866
+ stack[stack.length - 1].key = k;
2867
+ },
2868
+ endObject: () => put({ TAG: "Object", _0: stack.pop().entries }),
2869
+ flat(v, writeFlat) {
2870
+ writeFlat(v, $jsonFlat(builder));
2871
+ },
2872
+ };
2873
+ try {
2874
+ write(value, builder);
2875
+ } catch (e) {
2876
+ if (e instanceof $JsonError) return { TAG: "Err", _0: { message: e.message, line: e.line, column: e.column } };
2877
+ throw e;
2878
+ }
2879
+ return { TAG: "Ok", _0: root };
2880
+ }
2881
+
2882
+ export function $displayJsonError(e) {
2883
+ return e.line === 0 ? e.message : `${e.message} at line ${e.line} column ${e.column}`;
2884
+ }
2885
+ export function $debugJsonError(e) {
2886
+ return `Error(${$debugStr(e.message)}, line: ${e.line}, column: ${e.column})`;
2887
+ }
2888
+
2889
+ export function $lowerExp(x) {
2890
+ if (Number.isNaN(x)) return "NaN";
2891
+ if (!Number.isFinite(x)) return x > 0 ? "inf" : "-inf";
2892
+ return x.toExponential().replace("e+", "e");
2893
+ }
2894
+
2895
+ export function $fromDigit(num, radix) {
2896
+ if (radix > 36) throw new Error("from_digit: radix is too high (maximum 36)");
2897
+ return num < radix ? String.fromCharCode(num < 10 ? 48 + num : 87 + num) : undefined;
2898
+ }
2899
+
2900
+ export function $fromU32(n) {
2901
+ return n > 0x10ffff || (n >= 0xd800 && n <= 0xdfff) ? undefined : String.fromCodePoint(n);
2902
+ }
2903
+
2904
+ export function $totalCmp(a, b) {
2905
+ const view = new DataView(new ArrayBuffer(16));
2906
+ view.setFloat64(0, a);
2907
+ view.setFloat64(8, b);
2908
+ const ordered = (bits) => bits ^ BigInt.asIntN(64, BigInt.asUintN(64, bits >> 63n) >> 1n);
2909
+ const x = ordered(view.getBigInt64(0));
2910
+ const y = ordered(view.getBigInt64(8));
2911
+ return x < y ? -1 : x > y ? 1 : 0;
2912
+ }
2913
+
2914
+ export function $drain(items, start, end = items.length) {
2915
+ if (start > end) throw new Error(`slice index starts at ${start} but ends at ${end}`);
2916
+ if (end > items.length) throw new Error(`range end index ${end} out of range for slice of length ${items.length}`);
2917
+ return items.splice(start, end - start);
2918
+ }
2919
+
2920
+ export function $splitOff(items, at) {
2921
+ if (at > items.length) throw new Error(`\`at\` split index (is ${at}) should be <= len (is ${items.length})`);
2922
+ return items.splice(at);
2923
+ }
2924
+
2925
+ export function $peek(it) {
2926
+ return it.items[it.at];
2927
+ }
2928
+
2929
+ export function $nextIf(it, f) {
2930
+ return it.at < it.items.length && f(it.items[it.at]) ? it.items[it.at++] : undefined;
2931
+ }
2932
+
2933
+ export function $rest(it) {
2934
+ const rest = it.items.slice(it.at);
2935
+ it.at = it.items.length;
2936
+ return rest;
2937
+ }
2938
+
2939
+ export function $restStr(it) {
2940
+ return it.items.slice(it.at).join("");
2941
+ }
2942
+
2943
+ export function $unwrapErr(result, message = "called `Result::unwrap_err()` on an `Ok` value") {
2944
+ if (result.TAG === "Ok") {
2945
+ throw new Error(message + ": " + $debug(result._0));
2946
+ }
2947
+ return result._0;
2948
+ }
2949
+
2950
+ export function $debugParseError(message, name) {
2951
+ const kinds = {
2952
+ "cannot parse integer from empty string": "Empty",
2953
+ "invalid digit found in string": "InvalidDigit",
2954
+ "number too large to fit in target type": "PosOverflow",
2955
+ "number too small to fit in target type": "NegOverflow",
2956
+ "number would be zero for non-zero type": "Zero",
2957
+ "cannot parse float from empty string": "Empty",
2958
+ "invalid float literal": "Invalid",
2959
+ "cannot parse char from empty string": "EmptyString",
2960
+ "too many characters in string": "TooManyChars",
2961
+ };
2962
+ if (name === "TryFromIntError") return `TryFromIntError(${message})`;
2963
+ return name === "ParseBoolError" ? name : `${name} { kind: ${kinds[message]} }`;
2964
+ }
2965
+
2966
+ export function $siftUp(heap, start, pos, cmp) {
2967
+ const item = heap[pos];
2968
+ while (pos > start) {
2969
+ const parent = (pos - 1) >>> 1;
2970
+ if (cmp(item, heap[parent]) <= 0) {
2971
+ break;
2972
+ }
2973
+ heap[pos] = heap[parent];
2974
+ pos = parent;
2975
+ }
2976
+ heap[pos] = item;
2977
+ return pos;
2978
+ }
2979
+
2980
+ export function $siftDown(heap, pos, end, cmp) {
2981
+ const item = heap[pos];
2982
+ let child = 2 * pos + 1;
2983
+ while (child <= end - 2) {
2984
+ if (cmp(heap[child], heap[child + 1]) <= 0) {
2985
+ child += 1;
2986
+ }
2987
+ if (cmp(item, heap[child]) >= 0) {
2988
+ heap[pos] = item;
2989
+ return pos;
2990
+ }
2991
+ heap[pos] = heap[child];
2992
+ pos = child;
2993
+ child = 2 * pos + 1;
2994
+ }
2995
+ if (child === end - 1 && cmp(item, heap[child]) < 0) {
2996
+ heap[pos] = heap[child];
2997
+ pos = child;
2998
+ }
2999
+ heap[pos] = item;
3000
+ return pos;
3001
+ }
3002
+
3003
+ export function $heapPush(heap, item, cmp) {
3004
+ heap.push(item);
3005
+ $siftUp(heap, 0, heap.length - 1, cmp);
3006
+ }
3007
+
3008
+ export function $heapPop(heap, cmp) {
3009
+ if (heap.length === 0) {
3010
+ return undefined;
3011
+ }
3012
+ let top = heap.pop();
3013
+ if (heap.length > 0) {
3014
+ [top, heap[0]] = [heap[0], top];
3015
+ const end = heap.length;
3016
+ const item = heap[0];
3017
+ let pos = 0;
3018
+ let child = 1;
3019
+ while (child <= end - 2) {
3020
+ if (cmp(heap[child], heap[child + 1]) <= 0) {
3021
+ child += 1;
3022
+ }
3023
+ heap[pos] = heap[child];
3024
+ pos = child;
3025
+ child = 2 * pos + 1;
3026
+ }
3027
+ if (child === end - 1) {
3028
+ heap[pos] = heap[child];
3029
+ pos = child;
3030
+ }
3031
+ heap[pos] = item;
3032
+ $siftUp(heap, 0, pos, cmp);
3033
+ }
3034
+ return top;
3035
+ }
3036
+
3037
+ export function $heapSorted(items, cmp) {
3038
+ const heap = items.slice();
3039
+ let end = heap.length;
3040
+ while (end > 1) {
3041
+ end -= 1;
3042
+ [heap[0], heap[end]] = [heap[end], heap[0]];
3043
+ $siftDown(heap, 0, end, cmp);
3044
+ }
3045
+ return heap;
3046
+ }
3047
+
3048
+ export function $heapFrom(items, cmp) {
3049
+ const heap = items.slice();
3050
+ let n = heap.length >>> 1;
3051
+ while (n > 0) {
3052
+ n -= 1;
3053
+ $siftDown(heap, n, heap.length, cmp);
3054
+ }
3055
+ return heap;
3056
+ }
3057
+
3058
+ export function $parseInt(s, min, max) {
3059
+ const error = (message) => ({ TAG: "Err", _0: message });
3060
+ if (s === "") return error("cannot parse integer from empty string");
3061
+ if (!(min < 0 ? /^[+-]?[0-9]+$/ : /^\+?[0-9]+$/).test(s)) return error("invalid digit found in string");
3062
+ const n = Number(s);
3063
+ if (n > max) return error("number too large to fit in target type");
3064
+ if (n < min) return error("number too small to fit in target type");
3065
+ return { TAG: "Ok", _0: n };
3066
+ }
3067
+
3068
+ export function $parseF64(s) {
3069
+ if (s === "") return { TAG: "Err", _0: "cannot parse float from empty string" };
3070
+ const lower = s.toLowerCase();
3071
+ const sign = lower.startsWith("-") ? -1 : 1;
3072
+ const rest = lower.replace(/^[+-]/, "");
3073
+ if (rest === "inf" || rest === "infinity") return { TAG: "Ok", _0: sign * Infinity };
3074
+ if (rest === "nan") return { TAG: "Ok", _0: NaN };
3075
+ if (!/^([0-9]+\.?[0-9]*|\.[0-9]+)(e[+-]?[0-9]+)?$/.test(rest)) return { TAG: "Err", _0: "invalid float literal" };
3076
+ return { TAG: "Ok", _0: sign * Number(rest) };
3077
+ }
3078
+
3079
+ export function $parseBool(s) {
3080
+ return s === "true" || s === "false"
3081
+ ? { TAG: "Ok", _0: s === "true" }
3082
+ : { TAG: "Err", _0: "provided string was not `true` or `false`" };
3083
+ }
3084
+
3085
+ export function $parseChar(s) {
3086
+ const chars = [...s];
3087
+ if (chars.length === 1) return { TAG: "Ok", _0: s };
3088
+ return { TAG: "Err", _0: chars.length === 0 ? "cannot parse char from empty string" : "too many characters in string" };
3089
+ }
3090
+
3091
+ export function $slice(items, start, end = items.length) {
3092
+ if (start > end) throw new Error(`slice index starts at ${start} but ends at ${end}`);
3093
+ if (end > items.length) throw new Error(`range end index ${end} out of range for slice of length ${items.length}`);
3094
+ return items.slice(start, end);
3095
+ }
3096
+
3097
+ export function $sliceEnd(items, start, end = items.length) {
3098
+ if (start > end) throw new Error(`slice index starts at ${start} but ends at ${end}`);
3099
+ if (end > items.length) throw new Error(`range end index ${end} out of range for slice of length ${items.length}`);
3100
+ return end;
3101
+ }
3102
+
3103
+ export function $extend(v, items) {
3104
+ for (const item of items) {
3105
+ v.push(item);
3106
+ }
3107
+ }
3108
+
3109
+ export function $insertAt(v, index, item) {
3110
+ if (index > v.length) {
3111
+ throw new Error(`insertion index (is ${index}) should be <= len (is ${v.length})`);
3112
+ }
3113
+ v.splice(index, 0, item);
3114
+ }
3115
+
3116
+ export function $removeAt(v, index) {
3117
+ if (index >= v.length) {
3118
+ throw new Error(`removal index (is ${index}) should be < len (is ${v.length})`);
3119
+ }
3120
+ return v.splice(index, 1)[0];
3121
+ }
3122
+
3123
+ export function $swap(v, a, b) {
3124
+ if (a >= v.length || b >= v.length) {
3125
+ throw new Error(`index out of bounds: the len is ${v.length} but the index is ${Math.max(a, b)}`);
3126
+ }
3127
+ [v[a], v[b]] = [v[b], v[a]];
3128
+ }
3129
+
3130
+ export function $truncate(v, length) {
3131
+ if (length < v.length) {
3132
+ v.length = length;
3133
+ }
3134
+ }
3135
+
3136
+ export function $dedup(v) {
3137
+ let n = 0;
3138
+ for (const item of v) {
3139
+ if (n === 0 || v[n - 1] !== item) {
3140
+ v[n++] = item;
3141
+ }
3142
+ }
3143
+ v.length = n;
3144
+ }
3145
+
3146
+ export function $windows(v, size) {
3147
+ if (size === 0) {
3148
+ throw new Error("window size must be non-zero");
3149
+ }
3150
+ return Array.from({ length: Math.max(0, v.length - size + 1) }, (_, i) => v.slice(i, i + size));
3151
+ }
3152
+
3153
+ export function $chunks(v, size) {
3154
+ if (size === 0) {
3155
+ throw new Error("chunk size must be non-zero");
3156
+ }
3157
+ return Array.from({ length: Math.ceil(v.length / size) }, (_, i) => v.slice(i * size, i * size + size));
3158
+ }
3159
+
3160
+ export function $zip(a, b) {
3161
+ return Array.from({ length: Math.min(a.length, b.length) }, (_, i) => [a[i], b[i]]);
3162
+ }
3163
+
3164
+ export function $takeWhile(items, keep) {
3165
+ const end = items.findIndex((item) => !keep(item));
3166
+ return end < 0 ? items.slice() : items.slice(0, end);
3167
+ }
3168
+
3169
+ export function $skipWhile(items, skip) {
3170
+ const start = items.findIndex((item) => !skip(item));
3171
+ return start < 0 ? [] : items.slice(start);
3172
+ }
3173
+
3174
+ export function $partition(items, keep) {
3175
+ const yes = [];
3176
+ const no = [];
3177
+ for (const item of items) {
3178
+ (keep(item) ? yes : no).push(item);
3179
+ }
3180
+ return [yes, no];
3181
+ }
3182
+
3183
+ export function $sortedKeys(set, cmp) {
3184
+ return Array.from(set).sort(cmp);
3185
+ }
3186
+
3187
+ export function $stripPrefix(s, prefix) {
3188
+ return s.startsWith(prefix) ? s.slice(prefix.length) : undefined;
3189
+ }
3190
+
3191
+ export function $stripSuffix(s, suffix) {
3192
+ return s.endsWith(suffix) ? s.slice(0, s.length - suffix.length) : undefined;
3193
+ }
3194
+
3195
+ export function $splitOnce(s, separator) {
3196
+ const i = s.indexOf(separator);
3197
+ return i < 0 ? undefined : [s.slice(0, i), s.slice(i + separator.length)];
3198
+ }
3199
+
3200
+ export function $rsplitOnce(s, separator) {
3201
+ const i = s.lastIndexOf(separator);
3202
+ return i < 0 ? undefined : [s.slice(0, i), s.slice(i + separator.length)];
3203
+ }
3204
+
3205
+ export function $try(f) {
3206
+ try {
3207
+ return { TAG: "Ok", _0: f() };
3208
+ } catch (e) {
3209
+ return { TAG: "Err", _0: e };
3210
+ }
3211
+ }
3212
+
3213
+ export function $settle(promise) {
3214
+ return promise.then((value) => ({ TAG: "Ok", _0: value }), (e) => ({ TAG: "Err", _0: e }));
3215
+ }
3216
+
3217
+ export function $unwrapOk(result, message = "called `Result::unwrap()` on an `Err` value", debug = $debug) {
3218
+ if (result.TAG === "Err") {
3219
+ throw new Error(message + ": " + debug(result._0));
3220
+ }
3221
+ return result._0;
3222
+ }
3223
+
3224
+ export function $range(start, end) {
3225
+ return Array.from({ length: Math.max(0, end - start) }, (_, i) => start + i);
3226
+ }
3227
+
3228
+ export function $cmp(a, b) {
3229
+ return a < b ? -1 : a > b ? 1 : 0;
3230
+ }
3231
+
3232
+ export function $partialCmp(a, b) {
3233
+ return a < b ? -1 : a > b ? 1 : a === b ? 0 : undefined;
3234
+ }
3235
+
3236
+ export function $toFixed(value, digits) {
3237
+ if (Number.isNaN(value)) return "NaN";
3238
+ if (value === Infinity) return "inf";
3239
+ if (value === -Infinity) return "-inf";
3240
+ const sign = value < 0 || Object.is(value, -0) ? "-" : "";
3241
+ const view = new DataView(new ArrayBuffer(8));
3242
+ view.setFloat64(0, Math.abs(value));
3243
+ const bits = view.getBigUint64(0);
3244
+ const exponent = Number((bits >> 52n) & 2047n);
3245
+ const fraction = bits & ((1n << 52n) - 1n);
3246
+ const significand = exponent === 0 ? fraction : fraction | (1n << 52n);
3247
+ const shift = exponent === 0 ? -1074 : exponent - 1075;
3248
+ // |value| * 10^digits, as a fraction.
3249
+ let numerator = significand * 10n ** BigInt(digits);
3250
+ let denominator = 1n;
3251
+ if (shift >= 0) numerator <<= BigInt(shift);
3252
+ else denominator <<= BigInt(-shift);
3253
+ let rounded = numerator / denominator;
3254
+ const twice = 2n * (numerator % denominator);
3255
+ if (twice > denominator || (twice === denominator && rounded % 2n === 1n)) rounded += 1n;
3256
+ const text = rounded.toString().padStart(digits + 1, "0");
3257
+ return sign + (digits === 0 ? text : text.slice(0, -digits) + "." + text.slice(-digits));
3258
+ }
3259
+
3260
+ export function $debugF64(value) {
3261
+ const size = Math.abs(value);
3262
+ if (Number.isFinite(value) && size !== 0 && (size < 1e-4 || size >= 1e16)) {
3263
+ return value.toExponential().replace("e+", "e");
3264
+ }
3265
+ const text = $displayF64(value);
3266
+ return Number.isFinite(value) && !text.includes(".") ? text + ".0" : text;
3267
+ }
3268
+
3269
+ export function $debugStr(s, quote = '"') {
3270
+ let out = quote;
3271
+ for (const c of s) {
3272
+ if (c === quote || c === "\\") out += "\\" + c;
3273
+ else if (c === "\n") out += "\\n";
3274
+ else if (c === "\r") out += "\\r";
3275
+ else if (c === "\t") out += "\\t";
3276
+ else if (c === "\0") out += "\\0";
3277
+ else if (/[\p{Cc}\p{Cf}\p{Cs}\p{Co}\p{Cn}\p{Zl}\p{Zp}\p{Grapheme_Extend}]/u.test(c) || (c !== " " && /\p{Zs}/u.test(c)))
3278
+ out += "\\u{" + c.codePointAt(0).toString(16) + "}";
3279
+ else out += c;
3280
+ }
3281
+ return out + quote;
3282
+ }
3283
+
3284
+ export function $debugFields(name, fields, values) {
3285
+ return name + " { " + fields.map((field, i) => field + ": " + values[i]).join(", ") + " }";
3286
+ }
3287
+
3288
+ export function $plus(text) {
3289
+ return text.startsWith("-") || text === "NaN" ? text : "+" + text;
3290
+ }
3291
+
3292
+ export function $zeroPad(text, width) {
3293
+ const head = /^[+-]?(0[xbo])?/.exec(text)[0];
3294
+ return head + text.slice(head.length).padStart(width - head.length, "0");
3295
+ }
3296
+
3297
+ export function $pad(text, width, align, fill = " ") {
3298
+ const room = width - [...text].length;
3299
+ if (room <= 0) return text;
3300
+ const before = align === ">" ? room : align === "^" ? Math.floor(room / 2) : 0;
3301
+ return fill.repeat(before) + text + fill.repeat(room - before);
3302
+ }
3303
+
3304
+ export function $cmpIn(names, a, b) {
3305
+ return $cmp(names.indexOf(a), names.indexOf(b));
3306
+ }
3307
+
3308
+ export function $cmpItems(a, b, cmp) {
3309
+ for (let i = 0; i < a.length && i < b.length; i++) {
3310
+ const order = cmp(a[i], b[i]);
3311
+ if (order !== 0) {
3312
+ return order;
3313
+ }
3314
+ }
3315
+ return $cmp(a.length, b.length);
3316
+ }
3317
+
3318
+ export function $thenCmp(...orders) {
3319
+ for (const order of orders) {
3320
+ if (order !== 0) {
3321
+ return order;
3322
+ }
3323
+ }
3324
+ return 0;
3325
+ }
3326
+
3327
+ export function $maxBy(items, cmp, boxed = false) {
3328
+ if (items.length === 0) {
3329
+ return undefined;
3330
+ }
3331
+ const max = items.reduce((max, x) => (cmp(x, max) >= 0 ? x : max));
3332
+ return boxed ? $some(max) : max;
3333
+ }
3334
+
3335
+ export function $minBy(items, cmp, boxed = false) {
3336
+ if (items.length === 0) {
3337
+ return undefined;
3338
+ }
3339
+ const min = items.reduce((min, x) => (cmp(x, min) < 0 ? x : min));
3340
+ return boxed ? $some(min) : min;
3341
+ }
3342
+
3343
+ export function $max(items) {
3344
+ return items.length === 0 ? undefined : items.reduce((max, x) => (x >= max ? x : max));
3345
+ }
3346
+
3347
+ export function $min(items) {
3348
+ return items.length === 0 ? undefined : items.reduce((min, x) => (x < min ? x : min));
3349
+ }
3350
+
3351
+ export function $position(items, found) {
3352
+ const i = items.findIndex(found);
3353
+ return i < 0 ? undefined : i;
3354
+ }