Skip to content

Commit

Permalink
S.compile (#91)
Browse files Browse the repository at this point in the history
* S.compile

* Finish S.compile implementation
  • Loading branch information
DZakh authored Sep 25, 2024
1 parent 0282840 commit 2ea9c45
Show file tree
Hide file tree
Showing 10 changed files with 375 additions and 178 deletions.
21 changes: 18 additions & 3 deletions IDEAS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,32 @@ let trimContract: S.contract<string => string> = S.contract(s => {

## v9

- Add S.reverse
- Remove ...OrThrow from js/ts api
- Add mode/flags instead of operation
- Simplify caching by the mode/flag
- Add S./"~experimentalReverse"
- S.transform(s => {
s.reverse(input => input) // Or s.asyncReverse(input => Promise.resolve(input))
input => input
}) // or asyncTransform // Maybe format ?
- async serializing support
- Add S.unwrap
- Rename S.variant to something
- Rename serialize to convertReverse
- Add S.removeTypeValidation
- S.create / S.validate
- S.parseToJsonString
- Rename S.inline to S.toRescriptCode
- Add serializeToJsonString to js api
- Add S.bigint
- Fix reverse for object/tuple/variant/recursive

### Done

- Add S.compile

## v10

- Make S.serializeToJsonString super fast
- Add S.bigint
- Add S.promise

## v???
Expand Down
23 changes: 15 additions & 8 deletions packages/tests/src/benchmark/Benchmark.bs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -210,19 +210,26 @@ S$RescriptSchema.$$Error.make({

console.timeEnd("S.Error.make");

run(addWithPrepare(addWithPrepare(addWithPrepare(addWithPrepare(addWithPrepare(addWithPrepare(addWithPrepare(addWithPrepare(new (Benchmark.default.Suite)(), "Parse string", (function () {
run(addWithPrepare(addWithPrepare(addWithPrepare(addWithPrepare(addWithPrepare(addWithPrepare(addWithPrepare(addWithPrepare(addWithPrepare(new (Benchmark.default.Suite)(), "Parse string", (function () {
return function () {
return S$RescriptSchema.parseAnyOrRaiseWith("Hello world!", S$RescriptSchema.string);
};
})), "Serialize string", (function () {
return function () {
return S$RescriptSchema.parseAnyOrRaiseWith("Hello world!", S$RescriptSchema.string);
return S$RescriptSchema.serializeOrRaiseWith("Hello world!", S$RescriptSchema.string);
};
})), "Serialize string", (function () {
return function () {
return S$RescriptSchema.serializeOrRaiseWith("Hello world!", S$RescriptSchema.string);
};
})).add("Advanced object schema factory", makeAdvancedObjectSchema), "Parse advanced object", (function () {
})).add("Advanced object schema factory", makeAdvancedObjectSchema), "Parse advanced object", (function () {
var schema = makeAdvancedObjectSchema();
var data = makeTestObject();
return function () {
return S$RescriptSchema.parseAnyOrRaiseWith(data, schema);
};
})), "Assert advanced object - compile", (function () {
var schema = makeAdvancedObjectSchema();
var data = makeTestObject();
var assertFn = S$RescriptSchema.compile(schema, "Any", "Assert", true);
return function () {
return S$RescriptSchema.parseAnyOrRaiseWith(data, schema);
assertFn(data);
};
})), "Assert advanced object", (function () {
var schema = makeAdvancedObjectSchema();
Expand Down
8 changes: 8 additions & 0 deletions packages/tests/src/benchmark/Benchmark.res
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,14 @@ Suite.make()
data->S.parseAnyOrRaiseWith(schema)
}
})
->Suite.addWithPrepare("Assert advanced object - compile", () => {
let schema = makeAdvancedObjectSchema()
let data = makeTestObject()
let assertFn = schema->S.compile(~input=Any, ~output=Assert, ~typeValidation=true)
() => {
assertFn(data)
}
})
->Suite.addWithPrepare("Assert advanced object", () => {
let schema = makeAdvancedObjectSchema()
let data = makeTestObject()
Expand Down
17 changes: 6 additions & 11 deletions packages/tests/src/utils/U.bs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -78,35 +78,30 @@ function unsafeAssertEqualSchemas(t, s1, s2, message) {
function assertCompiledCode(t, schema, op, code, message) {
var compiledCode;
if (op === "Assert") {
try {
S$RescriptSchema.assertOrRaiseWith(undefined, schema);
}
catch (exn){

}
compiledCode = (schema.assert.toString());
var fn = S$RescriptSchema.compile(schema, "Any", "Assert", true);
compiledCode = fn.toString();
} else if (op === "SerializeJson") {
try {
S$RescriptSchema.serializeOrRaiseWith(undefined, schema);
}
catch (exn$1){
catch (exn){

}
compiledCode = (schema.serializeToJsonOrThrow.toString());
} else if (op === "Serialize") {
try {
S$RescriptSchema.serializeToUnknownOrRaiseWith(undefined, schema);
}
catch (exn$2){
catch (exn$1){

}
compiledCode = (schema.serializeOrThrow.toString());
} else if (S$RescriptSchema.isAsyncParse(schema)) {
S$RescriptSchema.parseAsyncWith(undefined, schema);
compiledCode = (schema.a.toString());
} else {
S$RescriptSchema.parseAnyWith(undefined, schema);
compiledCode = (schema.parseOrThrow.toString());
var fn$1 = S$RescriptSchema.compile(schema, "Any", "Output", true);
compiledCode = fn$1.toString();
}
t.is(compiledCode, code, message !== undefined ? Caml_option.valFromOption(message) : undefined);
}
Expand Down
12 changes: 4 additions & 8 deletions packages/tests/src/utils/U.res
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,12 @@ let assertCompiledCode = (
let _ = %raw(`undefined`)->S.parseAsyncWith(schema)
%raw(`schema.a.toString()`)
} else {
let _ = %raw(`undefined`)->S.parseAnyWith(schema)
%raw(`schema.parseOrThrow.toString()`)
let fn = schema->S.compile(~input=Any, ~output=Output, ~typeValidation=true)
(fn->magic)["toString"]()
}
| #Assert =>
try {
let _ = %raw(`undefined`)->S.assertOrRaiseWith(schema)
} catch {
| _ => ()
}
%raw(`schema.assert.toString()`)
let fn = schema->S.compile(~input=Any, ~output=Assert, ~typeValidation=true)
(fn->magic)["toString"]()
| #Serialize => {
try {
let _ = %raw(`undefined`)->S.serializeToUnknownOrRaiseWith(schema)
Expand Down
3 changes: 3 additions & 0 deletions src/S.bs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ var refine = S_Core$RescriptSchema.refine;

var variant = S_Core$RescriptSchema.variant;

var compile = S_Core$RescriptSchema.compile;

var parseWith = S_Core$RescriptSchema.parseWith;

var parseAnyWith = S_Core$RescriptSchema.parseAnyWith;
Expand Down Expand Up @@ -210,6 +212,7 @@ export {
custom ,
refine ,
variant ,
compile ,
parseWith ,
parseAnyWith ,
parseJsonStringWith ,
Expand Down
20 changes: 20 additions & 0 deletions src/S.resi
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,26 @@ let refine: (t<'value>, s<'value> => 'value => unit) => t<'value>

let variant: (t<'value>, 'value => 'variant) => t<'variant>

type rec input<'input, 'computed> =
| Input: input<'input, 'input>
| Any: input<'input, 'any>
| Unknown: input<'input, unknown>
| Json: input<'input, Js.Json.t>
| JsonString: input<'input, string>
type rec output<'output, 'computed> =
| Output: output<'output, 'output>
| Unknown: output<'output, unknown>
| Assert: output<'output, unit>
| Json: output<'output, Js.Json.t>
| JsonString: output<'output, string>

let compile: (
t<'schemaOutput>,
~input: input<unknown, 'input>,
~output: output<'schemaOutput, 'output>,
~typeValidation: bool,
) => 'input => 'output

let parseWith: (Js.Json.t, t<'value>) => result<'value, error>

let parseAnyWith: ('any, t<'value>) => result<'value, error>
Expand Down
Loading

1 comment on commit 2ea9c45

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 2ea9c45 Previous: 90ab99c Ratio
Parse string 809705308 ops/sec (±0.15%) 811431552 ops/sec (±0.15%) 1.00
Serialize string 810383784 ops/sec (±0.23%) 812781945 ops/sec (±0.05%) 1.00
Advanced object schema factory 459236 ops/sec (±1.04%) 472293 ops/sec (±0.54%) 1.03
Parse advanced object 55739506 ops/sec (±0.25%) 56799894 ops/sec (±0.57%) 1.02
Assert advanced object - compile 163509880 ops/sec (±0.14%)
Assert advanced object 171869112 ops/sec (±0.15%) 171920805 ops/sec (±0.20%) 1.00
Create and parse advanced object 94623 ops/sec (±0.22%) 95083 ops/sec (±0.21%) 1.00
Parse advanced strict object 25281326 ops/sec (±0.32%) 25471962 ops/sec (±0.17%) 1.01
Assert advanced strict object 30124643 ops/sec (±0.55%) 30460141 ops/sec (±0.20%) 1.01
Serialize advanced object 71875086 ops/sec (±0.28%) 74797850 ops/sec (±0.32%) 1.04

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.