Skip to content

Commit d3f97b3

Browse files
committed
feat: 🎸 support inline Value in capacity estimator codegen
1 parent 2485c07 commit d3f97b3

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

src/codegen/capacity/CapacityEstimatorCodegen.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {DiscriminatorCodegen} from '../discriminator';
88
import {lazyKeyedFactory} from '../util';
99
import {AbstractCodegen} from '../AbstractCodege';
1010
import type {SchemaPath} from '../types';
11+
import {Value} from '../../value';
1112

1213
export type CompiledCapacityEstimator = (value: unknown) => number;
1314

@@ -36,6 +37,10 @@ export class CapacityEstimatorCodegen extends AbstractCodegen<CompiledCapacityEs
3637
args: ['r0'],
3738
prologue: /* js */ `var size = 0;`,
3839
epilogue: /* js */ `return size;`,
40+
linkable: {
41+
Value,
42+
get: CapacityEstimatorCodegen.get,
43+
},
3944
processSteps: (steps) => {
4045
const stepsJoined: CodegenStepExecJs[] = [];
4146
for (let i = 0; i < steps.length; i++) {
@@ -58,7 +63,19 @@ export class CapacityEstimatorCodegen extends AbstractCodegen<CompiledCapacityEs
5863
protected onAny(path: SchemaPath, r: JsExpression, type: AnyType): void {
5964
const codegen = this.codegen;
6065
const rv = codegen.var(r.use());
61-
codegen.js(/* js */ `size += maxEncodingCapacity(${rv});`);
66+
codegen.link('Value');
67+
codegen.link('get');
68+
codegen.if(/* js */ `${rv} instanceof Value`, () => {
69+
const rType = codegen.var(/* js */ `${rv}.type`);
70+
const rData = codegen.var(/* js */ `${rv}.data`);
71+
codegen.if(/* js */ `${rType}`, () => {
72+
codegen.js(/* js */ `size += get(${rType})(${rData});`);
73+
}, () => {
74+
codegen.js(/* js */ `size += maxEncodingCapacity(${rData});`);
75+
});
76+
}, () => {
77+
codegen.js(/* js */ `size += maxEncodingCapacity(${rv});`);
78+
});
6279
}
6380

6481
protected onCon(path: SchemaPath, r: JsExpression, type: ConType): void {

src/codegen/capacity/__tests__/CapacityEstimatorCodegenContext.spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {t} from '../../../type';
33
import {ModuleType} from '../../../type/classes/ModuleType';
44
import {CapacityEstimatorCodegen} from '../CapacityEstimatorCodegen';
55
import {Random} from '../../../random';
6+
import {unknown, Value} from '../../../value';
67

78
describe('"any" type', () => {
89
test('returns the same result as maxEncodingCapacity()', () => {
@@ -11,6 +12,26 @@ describe('"any" type', () => {
1112
const values = [null, true, false, 1, 123.123, '', 'adsf', [], {}, {foo: 'bar'}, [{a: [{b: null}]}]];
1213
for (const value of values) expect(estimator(value)).toBe(maxEncodingCapacity(value));
1314
});
15+
16+
test('can encode "any" field', () => {
17+
const type = t.object({foo: t.any});
18+
const estimator = CapacityEstimatorCodegen.get(type);
19+
expect(estimator({foo: true})).toBe(maxEncodingCapacity({foo: true}));
20+
});
21+
22+
test('can encode anon Value<unknown>', () => {
23+
const type = t.object({foo: t.any});
24+
const value = unknown('test');
25+
const estimator = CapacityEstimatorCodegen.get(type);
26+
expect(estimator({foo: value})).toBe(maxEncodingCapacity({foo: value.data}));
27+
});
28+
29+
test('can encode typed Value<T>', () => {
30+
const type = t.object({foo: t.any});
31+
const value = new Value(123, t.con(123));
32+
const estimator = CapacityEstimatorCodegen.get(type);
33+
expect(estimator({foo: value})).toBe(maxEncodingCapacity({foo: value.data}));
34+
});
1435
});
1536

1637
describe('"con" type', () => {

0 commit comments

Comments
 (0)