Skip to content

Commit ad74eeb

Browse files
committed
support arbitrary in structured types & support more primitive types
1 parent 6a7de5f commit ad74eeb

File tree

3 files changed

+1787
-85
lines changed

3 files changed

+1787
-85
lines changed

conway-cddl/codegen/generators/structured/index.ts

+64-10
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,32 @@ export class GenStructuredBase<
3131
}
3232

3333
private fieldType(field: Field) {
34-
return `${this.typeUtils.jsType(field.type)} ${field.optional || field.nullable ? "| undefined" : ""}`;
34+
return `${this.fieldBaseType(field)}${field.optional || field.nullable ? " | undefined" : ""}`;
35+
}
36+
37+
// this ignores undefined
38+
private fieldBaseType(field: Field) {
39+
return `${this.typeUtils.jsType(field.type)}`;
40+
}
41+
42+
// necessary because primitive fields do not have an arbitrary method
43+
private fieldArbitrary(field: Field, prng: string): string {
44+
let primitives: Set<string> = new Set(["Uint8Array", "number", "boolean"]);
45+
const fieldType: string = this.fieldBaseType(field);
46+
if (primitives.has(fieldType) ) {
47+
switch (fieldType) {
48+
case "Uint8Array":
49+
return `new Uint8Array(repeatRand(3, ${prng}, prand.uniformIntDistribution(0, 255))[0])`;
50+
case "number":
51+
return `prand.uniformIntDistribution(0, Number.MAX_SAFE_INTEGER, ${prng})[0]`;
52+
case "boolean":
53+
return `prand.unsafeUniformIntDistribution(0, 1, ${prng}) > 0`;
54+
default:
55+
throw new Error(`Unexpected primitive type ${fieldType}`);
56+
}
57+
} else {
58+
return `${field.type}.arbitrary(${prng})`;
59+
}
3560
}
3661

3762
getFields(): Field[] {
@@ -54,21 +79,21 @@ export class GenStructuredBase<
5479
.map((x) => `${x.name}: ${this.fieldType(x)}`)
5580
.join(", ")}) {
5681
${this.getFields()
57-
.map((x) => `this._${x.name} = ${x.name};`)
58-
.join("\n")}
82+
.map((x) => `this._${x.name} = ${x.name};`)
83+
.join("\n")}
5984
}
6085
${this.renameMethod(
61-
"new",
62-
(new_) => `
86+
"new",
87+
(new_) => `
6388
static ${new_}(${this.getFields()
64-
.map((x) => `${x.name}: ${this.fieldType(x)}`)
65-
.join(", ")}) {
89+
.map((x) => `${x.name}: ${this.fieldType(x)}`)
90+
.join(", ")}) {
6691
return new ${this.name}(${this.getFields()
67-
.map((x) => x.name)
68-
.join(",")});
92+
.map((x) => x.name)
93+
.join(",")});
6994
}
7095
`
71-
)}
96+
)}
7297
`;
7398
}
7499

@@ -96,6 +121,35 @@ export class GenStructuredBase<
96121
.join("\n");
97122
}
98123

124+
generateArbitrary(prng: string): string {
125+
const generateField = (f: Field) => {
126+
if (f.optional) {
127+
return `
128+
let ${f.name}: ${this.fieldType(f)};
129+
const ${f.name}_defined = prand.unsafeUniformIntDistribution(0, 1, ${prng});
130+
if (${f.name}_defined) {
131+
${f.name} = ${this.fieldArbitrary(f, prng)};
132+
prand.unsafeSkipN(${prng}, 1);
133+
} else {
134+
${f.name} = undefined;
135+
}
136+
`
137+
} else {
138+
return `
139+
let ${f.name}: ${this.fieldType(f)};
140+
${f.name} = ${this.fieldArbitrary(f, prng)};
141+
prand.unsafeSkipN(${prng}, 1);
142+
`
143+
}
144+
145+
}
146+
return `
147+
${this.getFields().map(generateField).join('\n')}
148+
149+
return new ${this.name}(${this.getFields().map((f) => f.name)});
150+
`
151+
}
152+
99153
generateExtraMethods(): string {
100154
return this.generateAccessors();
101155
}

conway-cddl/codegen/main.ts

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ async function main() {
7979
import {Address, Credential, CredKind, RewardAddress} from "./address";
8080
import { RandomGenerator } from 'pure-rand';
8181
import prand from 'pure-rand';
82+
import { repeatRand } from './lib/prand_utils';
8283
8384
function $$UN(id: string, ...args: any): any {
8485
throw ("Undefined function: " + id);

0 commit comments

Comments
 (0)