Skip to content

Commit 24917cc

Browse files
committed
feat(json-type): 🎸 add support for CBOR and MessagePack "map" type codegen encoders
1 parent eaacabd commit 24917cc

File tree

2 files changed

+54
-21
lines changed

2 files changed

+54
-21
lines changed

‎src/json-type/codegen/binary/__tests__/testBinaryCodegen.ts‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,40 @@ export const testBinaryCodegen = (transcode: (system: TypeSystem, type: Type, va
369369
});
370370
});
371371

372+
describe('"map" type', () => {
373+
test('can encode empty map', () => {
374+
const system = new TypeSystem();
375+
const t = system.t;
376+
const type = t.map;
377+
const value: {} = {};
378+
expect(transcode(system, type, value)).toStrictEqual(value);
379+
});
380+
381+
test('can encode empty map with one key', () => {
382+
const system = new TypeSystem();
383+
const t = system.t;
384+
const type = t.map;
385+
const value: {} = {a: 'asdf'};
386+
expect(transcode(system, type, value)).toStrictEqual(value);
387+
});
388+
389+
test('can encode typed map with two keys', () => {
390+
const system = new TypeSystem();
391+
const t = system.t;
392+
const type = t.Map(t.bool);
393+
const value: {} = {x: true, y: false};
394+
expect(transcode(system, type, value)).toStrictEqual(value);
395+
});
396+
397+
test('can encode nested maps', () => {
398+
const system = new TypeSystem();
399+
const t = system.t;
400+
const type = t.Map(t.Map(t.bool));
401+
const value: {} = {a: {x: true, y: false}}
402+
expect(transcode(system, type, value)).toStrictEqual(value);
403+
});
404+
});
405+
372406
describe('"ref" type', () => {
373407
test('can encode a simple reference', () => {
374408
const system = new TypeSystem();

‎src/json-type/type/classes.ts‎

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1950,32 +1950,30 @@ export class MapType<T extends Type> extends AbstractType<schema.MapSchema<Schem
19501950
}
19511951

19521952
private codegenBinaryEncoder(ctx: BinaryEncoderCodegenContext<BinaryJsonEncoder>, value: JsExpression): void {
1953-
throw new Error('TODO');
1954-
// const type = this.type;
1955-
// const codegen = ctx.codegen;
1956-
// const r = codegen.getRegister(); // array
1957-
// const rl = codegen.getRegister(); // array.length
1958-
// const ri = codegen.getRegister(); // index
1959-
// const rItem = codegen.getRegister(); // item
1960-
// const expr = new JsExpression(() => `${rItem}`);
1961-
// ctx.js(/* js */ `var ${r} = ${value.use()}, ${rl} = ${r}.length, ${ri} = 0, ${rItem};`);
1962-
// ctx.js(/* js */ `encoder.writeArrHdr(${rl});`);
1963-
// ctx.js(/* js */ `for(; ${ri} < ${rl}; ${ri}++) ` + '{');
1964-
// ctx.js(/* js */ `${rItem} = ${r}[${ri}];`);
1965-
// if (ctx instanceof CborEncoderCodegenContext) type.codegenCborEncoder(ctx, expr);
1966-
// else if (ctx instanceof MessagePackEncoderCodegenContext) type.codegenMessagePackEncoder(ctx, expr);
1967-
// else throw new Error('Unknown encoder');
1968-
// ctx.js(`}`);
1953+
const type = this.type;
1954+
const codegen = ctx.codegen;
1955+
const r = codegen.var(value.use());
1956+
const rKeys = codegen.var(`Object.keys(${r})`);
1957+
const rKey = codegen.var();
1958+
const rLength = codegen.var(`${rKeys}.length`);
1959+
const ri = codegen.var('0');
1960+
ctx.js(`encoder.writeObjHdr(${rLength});`);
1961+
ctx.js(`for(; ${ri} < ${rLength}; ${ri}++){`);
1962+
ctx.js(`${rKey} = ${rKeys}[${ri}];`);
1963+
ctx.js(`encoder.writeStr(${rKey});`);
1964+
const expr = new JsExpression(() => `${r}[${rKey}]`);
1965+
if (ctx instanceof CborEncoderCodegenContext) type.codegenCborEncoder(ctx, expr);
1966+
else if (ctx instanceof MessagePackEncoderCodegenContext) type.codegenMessagePackEncoder(ctx, expr);
1967+
else throw new Error('Unknown encoder');
1968+
ctx.js(`}`);
19691969
}
19701970

19711971
public codegenCborEncoder(ctx: CborEncoderCodegenContext, value: JsExpression): void {
1972-
throw new Error('TODO');
1973-
// this.codegenBinaryEncoder(ctx, value);
1972+
this.codegenBinaryEncoder(ctx, value);
19741973
}
19751974

19761975
public codegenMessagePackEncoder(ctx: MessagePackEncoderCodegenContext, value: JsExpression): void {
1977-
throw new Error('TODO');
1978-
// this.codegenBinaryEncoder(ctx, value);
1976+
this.codegenBinaryEncoder(ctx, value);
19791977
}
19801978

19811979
public codegenJsonEncoder(ctx: JsonEncoderCodegenContext, value: JsExpression): void {
@@ -2014,7 +2012,8 @@ export class MapType<T extends Type> extends AbstractType<schema.MapSchema<Schem
20142012
}
20152013

20162014
public codegenCapacityEstimator(ctx: CapacityEstimatorCodegenContext, value: JsExpression): void {
2017-
throw new Error('TODO CAP');
2015+
ctx.codegen.js(`size += maxEncodingCapacity(${value.use()});`);
2016+
// throw new Error('TODO CAP');
20182017
// const codegen = ctx.codegen;
20192018
// ctx.inc(MaxEncodingOverhead.Array);
20202019
// const rLen = codegen.var(`${value.use()}.length`);

0 commit comments

Comments
 (0)