Skip to content

Commit eb54774

Browse files
committed
feat: add new JSON.Obj type to represent dynamic objects
1 parent adcfe5a commit eb54774

File tree

1 file changed

+64
-6
lines changed

1 file changed

+64
-6
lines changed

assembly/index.ts

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { serializeMap } from "./serialize/simple/map";
77
import { deserializeBoolean } from "./deserialize/simple/bool";
88
import { deserializeArray } from "./deserialize/simple/array";
99
import { deserializeFloat } from "./deserialize/simple/float";
10-
import { deserializeObject } from "./deserialize/simple/object";
10+
import { deserializeStruct } from "./deserialize/simple/struct";
1111
import { deserializeMap } from "./deserialize/simple/map";
1212
import { deserializeDate } from "./deserialize/simple/date";
1313
import { deserializeInteger } from "./deserialize/simple/integer";
@@ -20,9 +20,11 @@ import { dtoa_buffered, itoa_buffered } from "util/number";
2020
import { serializeBool } from "./serialize/simple/bool";
2121
import { serializeInteger } from "./serialize/simple/integer";
2222
import { serializeFloat } from "./serialize/simple/float";
23-
import { serializeObject } from "./serialize/simple/object";
23+
import { serializeStruct } from "./serialize/simple/struct";
2424
import { ptrToStr } from "./util/ptrToStr";
2525
import { bytes } from "./util";
26+
import { deserializeArbitrary } from "./deserialize/simple/arbitrary";
27+
import { SERIALIZE_ESCAPE_TABLE } from "./globals/tables";
2628

2729
export type Raw = string;
2830

@@ -176,13 +178,16 @@ export namespace JSON {
176178
// @ts-ignore
177179
changetype<nonnull<T>>(out).__INITIALIZE();
178180
// @ts-ignore
179-
return deserializeObject<nonnull<T>>(dataPtr, dataPtr + dataSize, out);
181+
return deserializeStruct<nonnull<T>>(dataPtr, dataPtr + dataSize, out);
180182
} else if (type instanceof Map) {
181183
// @ts-ignore
182184
return deserializeMap<nonnull<T>>(dataPtr, dataPtr + dataSize);
183185
} else if (type instanceof Date) {
184186
// @ts-ignore
185187
return deserializeDate(dataPtr, dataPtr + dataSize);
188+
} else if (type instanceof JSON.Value) {
189+
// @ts-ignore
190+
return deserializeArbitrary(dataPtr, dataPtr + dataSize, 0);
186191
} else if (type instanceof JSON.Box) {
187192
// @ts-ignore
188193
return new JSON.Box(parseBox(data, changetype<nonnull<T>>(0).value));
@@ -278,6 +283,9 @@ export namespace JSON {
278283
if (!JSON.Value.METHODS.has(idof<T>())) JSON.Value.METHODS.set(idof<T>(), value.__SERIALIZE.index);
279284
// @ts-ignore
280285
store<T>(changetype<usize>(this), value, STORAGE);
286+
} else if (value instanceof JSON.Obj) {
287+
this.type = JSON.Types.Object;
288+
store<T>(changetype<usize>(this), value, STORAGE);
281289
// @ts-ignore
282290
} else if (isArray<T>() && idof<valueof<T>>() == idof<JSON.Value>()) {
283291
// @ts-ignore: T satisfies constraints of any[]
@@ -329,6 +337,9 @@ export namespace JSON {
329337
out.write("]");
330338
return out.toString();
331339
}
340+
case JSON.Types.Object: {
341+
return JSON.stringify(this.get<JSON.Obj>());
342+
}
332343
default: {
333344
const fn = JSON.Value.METHODS.get(this.type - JSON.Types.Struct);
334345
const value = this.get<usize>();
@@ -338,6 +349,49 @@ export namespace JSON {
338349
}
339350
}
340351

352+
export class Obj {
353+
private storage: Map<string, JSON.Value> = new Map<string, JSON.Value>();
354+
355+
private constructor() {
356+
unreachable();
357+
}
358+
359+
// @ts-ignore: decorator
360+
@inline set<T>(key: string, value: T): void {
361+
this.storage.set(key, Value.from<T>(value));
362+
}
363+
364+
// @ts-ignore: decorator
365+
@inline get(key: string): JSON.Value | null {
366+
if (!this.storage.has(key)) return null;
367+
return this.storage.get(key);
368+
}
369+
370+
// @ts-ignore: decorator
371+
@inline has(key: string): bool {
372+
return this.storage.has(key);
373+
}
374+
375+
// @ts-ignore: decorator
376+
@inline delete(key: string): bool {
377+
return this.storage.delete(key);
378+
}
379+
380+
// @ts-ignore: decorator
381+
@inline keys(): string[] {
382+
return this.storage.keys();
383+
}
384+
385+
// @ts-ignore: decorator
386+
@inline values(): JSON.Value[] {
387+
return this.storage.values();
388+
}
389+
390+
// @ts-ignore: decorator
391+
@inline toString(): string {
392+
return JSON.stringify(this);
393+
}
394+
}
341395
/**
342396
* Box for primitive types
343397
*/
@@ -389,7 +443,7 @@ export namespace JSON {
389443
// @ts-ignore: Supplied by transform
390444
} else if (isDefined(src.__SERIALIZE)) {
391445
// @ts-ignore
392-
serializeObject(changetype<nonnull<T>>(src));
446+
serializeStruct(changetype<nonnull<T>>(src));
393447
} else if (src instanceof Date) {
394448
// @ts-ignore
395449
serializeDate(changetype<nonnull<T>>(src));
@@ -425,7 +479,7 @@ export namespace JSON {
425479
let type: nonnull<T> = changetype<nonnull<T>>(0);
426480
// @ts-ignore: declared by transform
427481
if (isDefined(type.__DESERIALIZE)) {
428-
return deserializeObject<T>(srcStart, srcEnd, dst);
482+
return deserializeStruct<T>(srcStart, srcEnd, dst);
429483
} else if (type instanceof Map) {
430484
// @ts-ignore: type
431485
return deserializeMap<T>(srcStart, srcEnd, dst);
@@ -448,4 +502,8 @@ export namespace JSON {
448502

449503
function deserializeBox<T>(srcStart: usize, srcEnd: usize, dst: usize, ty: T): T {
450504
return JSON.__deserialize<T>(srcStart, srcEnd, dst);
451-
}
505+
}
506+
507+
export import Value = JSON.Value;
508+
export import Obj = JSON.Obj;
509+
export import Box = JSON.Box;

0 commit comments

Comments
 (0)