Skip to content

Commit

Permalink
v8.3.0 final fixes and improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
DZakh committed Sep 26, 2024
1 parent 8d499ba commit edae1ca
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 114 deletions.
11 changes: 7 additions & 4 deletions IDEAS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ let trimContract: S.contract<string => string> = S.contract(s => {

## v9

- Remove ...OrThrow from js/ts api
- Remove ...OrThrow/orRaise
- Add S.compile to Js/ts api
- Add mode/flags instead of operation
- Expose S.reverse
- S.transform(s => {
Expand All @@ -37,6 +38,7 @@ let trimContract: S.contract<string => string> = S.contract(s => {
- Add serializeToJsonString to js api
- Fix reverse for object/tuple/variant/recursive
- Rename disableNanNumberCheck
- Add tag for BigInt

### Done

Expand All @@ -46,9 +48,10 @@ let trimContract: S.contract<string => string> = S.contract(s => {
- Add S.unwrap
- S.isAsyncParse -> S.isAsync
- Add:
let convertWith: ('any, t<'value>) => result<'value, error>
let convertToJsonWith: ('any, t<'value>) => result<Js.Json.t, error>
let convertToJsonStringWith: ('any, t<'value>) => result<string, error>
let convertAnyWith: ('any, t<'value>) => result<'value, error>
let convertAnyToJsonWith: ('any, t<'value>) => result<Js.Json.t, error>
let convertAnyToJsonStringWith: ('any, t<'value>) => result<string, error>
let convertAnyAsyncWith: ('any, t<'value>) => promise<result<'value, error>>
- Deprecated S.parseOrRaiseWith, S.parseAnyOrRaiseWith, S.serializeOrRaiseWith, S.serializeToUnknownOrRaiseWith, S.serializeToJsonStringOrRaiseWith

## v10
Expand Down
53 changes: 30 additions & 23 deletions packages/tests/src/benchmark/Benchmark.bs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -210,56 +210,63 @@ S$RescriptSchema.$$Error.make({

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

run(addWithPrepare(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(addWithPrepare(new (Benchmark.default.Suite)(), "Parse string", (function () {
return function () {
return S$RescriptSchema.unwrap(S$RescriptSchema.parseAnyWith("Hello world!", S$RescriptSchema.string));
};
})), "Serialize string", (function () {
return function () {
return S$RescriptSchema.unwrap(S$RescriptSchema.parseAnyWith("Hello world!", S$RescriptSchema.string));
return S$RescriptSchema.unwrap(S$RescriptSchema.serializeWith("Hello world!", S$RescriptSchema.string));
};
})), "Serialize string", (function () {
return function () {
return S$RescriptSchema.unwrap(S$RescriptSchema.serializeWith("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.unwrap(S$RescriptSchema.parseAnyWith(data, schema));
};
})), "Assert advanced object - compile", (function () {
var schema = makeAdvancedObjectSchema();
var data = makeTestObject();
var assertFn = S$RescriptSchema.compile(schema, "Any", "Assert", "Sync", true);
return function () {
return S$RescriptSchema.unwrap(S$RescriptSchema.parseAnyWith(data, schema));
assertFn(data);
};
})), "Assert advanced object - compile", (function () {
})), "Assert advanced object", (function () {
var schema = makeAdvancedObjectSchema();
var data = makeTestObject();
var assertFn = S$RescriptSchema.compile(schema, "Any", "Assert", "Sync", true);
return function () {
assertFn(data);
S$RescriptSchema.assertOrRaiseWith(data, schema);
};
})), "Assert advanced object", (function () {
var schema = makeAdvancedObjectSchema();
})), "Create and parse advanced object", (function () {
var data = makeTestObject();
return function () {
S$RescriptSchema.assertOrRaiseWith(data, schema);
var schema = makeAdvancedObjectSchema();
return S$RescriptSchema.unwrap(S$RescriptSchema.parseAnyWith(data, schema));
};
})), "Create and parse advanced object", (function () {
})), "Parse advanced strict object", (function () {
var schema = makeAdvancedStrictObjectSchema();
var data = makeTestObject();
return function () {
var schema = makeAdvancedObjectSchema();
return S$RescriptSchema.unwrap(S$RescriptSchema.parseAnyWith(data, schema));
};
})), "Parse advanced strict object", (function () {
})), "Assert advanced strict object", (function () {
var schema = makeAdvancedStrictObjectSchema();
var data = makeTestObject();
return function () {
return S$RescriptSchema.unwrap(S$RescriptSchema.parseAnyWith(data, schema));
S$RescriptSchema.assertOrRaiseWith(data, schema);
};
})), "Assert advanced strict object", (function () {
var schema = makeAdvancedStrictObjectSchema();
})), "Serialize advanced object", (function () {
var schema = makeAdvancedObjectSchema();
var data = makeTestObject();
return function () {
S$RescriptSchema.assertOrRaiseWith(data, schema);
return S$RescriptSchema.unwrap(S$RescriptSchema.serializeWith(data, schema));
};
})), "Serialize advanced object", (function () {
})), "Serialize advanced object - compile", (function () {
var schema = makeAdvancedObjectSchema();
var data = makeTestObject();
var fn = S$RescriptSchema.compile(S$RescriptSchema.$tildeexperimentalReverse(schema), "Any", "Output", "Sync", false);
return function () {
return S$RescriptSchema.unwrap(S$RescriptSchema.serializeWith(data, schema));
return fn(data);
};
})));

Expand Down
29 changes: 11 additions & 18 deletions packages/tests/src/benchmark/Benchmark.res
Original file line number Diff line number Diff line change
Expand Up @@ -190,27 +190,9 @@ module CrazyUnion = {
Console.time("testData2 parse")
let _ = S.parseWith(json, schema)->S.unwrap
Console.timeEnd("testData2 parse")

// Console.log((schema->Obj.magic)["parseOrThrow"]["toString"]())
}
}

// Full
// testData1 serialize: 5.414s
// testData1 parse: 5.519s
// testData2 serialize: 70.864ms
// testData2 parse: 70.967ms

// Wip
// testData1 serialize: 5.843s
// testData1 parse: 5.625ms
// testData2 serialize: 64.489ms
// testData2 parse: 0.836ms

// Partial
// testData1 serialize: 1.802ms
// testData1 parse: 1.411ms
// 734 Error.make
CrazyUnion.test()

let data = makeTestObject()
Expand Down Expand Up @@ -312,6 +294,17 @@ Suite.make()
data->S.serializeWith(schema)->S.unwrap
}
})
->Suite.addWithPrepare("Serialize advanced object - compile", () => {
let schema = makeAdvancedObjectSchema()
let data = makeTestObject()
let fn =
schema
->S.\"~experimentalReverse"
->S.compile(~input=Any, ~output=Output, ~mode=Sync, ~typeValidation=false)
() => {
fn(data)
}
})
->Suite.run

/*
Expand Down
4 changes: 2 additions & 2 deletions packages/tests/src/benchmark/comparison.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ new B.Suite()
});
})
.add("rescript-schema (parse)", () => {
return schema.parseOrThrow(data);
return schema.parse(data);
})
.add("rescript-schema (create + parse)", () => {
const schema = S.object({
Expand All @@ -165,7 +165,7 @@ new B.Suite()
bool: S.boolean,
}),
});
return schema.parseOrThrow(data);
return schema.parse(data);
})
.on("cycle", (event) => {
console.log(String(event.target));
Expand Down
13 changes: 13 additions & 0 deletions packages/tests/src/core/S_bigint_test.res
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,19 @@ module Common = {
)
})

test("Fails to convert to Json", t => {
let schema = factory()

t->U.assertErrorResult(
value->S.convertAnyToJsonWith(schema),
{
code: InvalidJsonSchema(schema->S.toUnknown),
operation: SerializeToJson,
path: S.Path.empty,
},
)
})

test("BigInt name", t => {
let schema = factory()
t->Assert.is(schema->S.name, "BigInt", ())
Expand Down
80 changes: 32 additions & 48 deletions src/S_Core.bs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,11 @@ function noop(_b, input, param, param$1) {
return input;
}

function invalidJson(b, input, selfSchema, path) {
registerInvalidJson(b, selfSchema, path);
return input;
}

function noopOperation(i) {
return i;
}
Expand Down Expand Up @@ -727,33 +732,32 @@ function $tildeexperimentalReverse(schema) {
return schema.r();
}

function wrapExnToError(exn) {
if ((exn&&exn.s===symbol)) {
return {
TAG: "Error",
_0: exn
};
}
throw exn;
}

function asyncPrepareOk(value) {
return {
TAG: "Ok",
_0: value
};
}

function asyncPrepareError(jsExn) {
return {
TAG: "Error",
_0: getOrRethrow(jsExn)
};
}

function convertAnyWith(any, schema) {
try {
return {
TAG: "Ok",
_0: (schema[0] ? undefined : (schema[0] = compile(schema.b, schema, 0), undefined), schema[0](any))
};
}
catch (raw_exn){
var exn = Caml_js_exceptions.internalToOCamlException(raw_exn);
return {
TAG: "Error",
_0: getOrRethrow(exn)
};
catch (exn){
return wrapExnToError(exn);
}
}

Expand All @@ -764,12 +768,8 @@ function convertAnyToJsonWith(any, schema) {
_0: (schema[8] ? undefined : (schema[8] = compile(schema.b, schema, 8), undefined), schema[8](any))
};
}
catch (raw_exn){
var exn = Caml_js_exceptions.internalToOCamlException(raw_exn);
return {
TAG: "Error",
_0: getOrRethrow(exn)
};
catch (exn){
return wrapExnToError(exn);
}
}

Expand All @@ -780,25 +780,17 @@ function convertAnyToJsonStringWith(any, schema) {
_0: (schema[16] ? undefined : (schema[16] = compile(schema.b, schema, 16), undefined), schema[16](any))
};
}
catch (raw_exn){
var exn = Caml_js_exceptions.internalToOCamlException(raw_exn);
return {
TAG: "Error",
_0: getOrRethrow(exn)
};
catch (exn){
return wrapExnToError(exn);
}
}

function convertAnyAsyncWith(any, schema) {
try {
return (schema[2] ? undefined : (schema[2] = compile(schema.b, schema, 2), undefined), schema[2](any)).then(asyncPrepareOk, asyncPrepareError);
return (schema[2] ? undefined : (schema[2] = compile(schema.b, schema, 2), undefined), schema[2](any)).then(asyncPrepareOk, wrapExnToError);
}
catch (raw_exn){
var exn = Caml_js_exceptions.internalToOCamlException(raw_exn);
return Promise.resolve({
TAG: "Error",
_0: getOrRethrow(exn)
});
catch (exn){
return Promise.resolve(wrapExnToError(exn));
}
}

Expand Down Expand Up @@ -828,14 +820,10 @@ function parseAnyWith(any, schema) {

function parseAnyAsyncWith(any, schema) {
try {
return (schema[3] ? undefined : (schema[3] = compile(schema.b, schema, 3), undefined), schema[3](any)).then(asyncPrepareOk, asyncPrepareError);
return (schema[3] ? undefined : (schema[3] = compile(schema.b, schema, 3), undefined), schema[3](any)).then(asyncPrepareOk, wrapExnToError);
}
catch (raw_exn){
var exn = Caml_js_exceptions.internalToOCamlException(raw_exn);
return Promise.resolve({
TAG: "Error",
_0: getOrRethrow(exn)
});
catch (exn){
return Promise.resolve(wrapExnToError(exn));
}
}

Expand Down Expand Up @@ -1251,6 +1239,7 @@ function custom(name, definer) {
return makeSchema((function () {
return name;
}), "Unknown", empty, (function (b, input, selfSchema, path) {
registerInvalidJson(b, selfSchema, path);
var match = definer(effectCtx(b, selfSchema, path));
var parser = match.p;
if (parser !== undefined) {
Expand All @@ -1272,6 +1261,7 @@ function custom(name, definer) {
return makeReverseSchema((function () {
return name;
}), "Unknown", empty, (function (b, input, selfSchema, path) {
registerInvalidJson(b, selfSchema, path);
var match = definer(effectCtx(b, selfSchema, path));
var serializer = match.s;
if (serializer !== undefined) {
Expand All @@ -1292,10 +1282,7 @@ function literal(value) {
}), {
TAG: "Literal",
_0: literal$1
}, empty, literal$1.j ? noop : (function (b, input, selfSchema, path) {
registerInvalidJson(b, selfSchema, path);
return input;
}), (function (b, inputVar) {
}, empty, literal$1.j ? noop : invalidJson, (function (b, inputVar) {
return literal$1.f(b, inputVar, literal$1);
}), toSelf);
}
Expand Down Expand Up @@ -1931,10 +1918,7 @@ function factory$4(schema) {
}), typeFilter$1, onlyChild(factory$4, schema));
}

var schema$1 = makeSchema(primitiveName, "Unknown", empty, (function (b, input, selfSchema, path) {
registerInvalidJson(b, selfSchema, path);
return input;
}), undefined, toSelf);
var schema$1 = makeSchema(primitiveName, "Unknown", empty, invalidJson, undefined, toSelf);

var metadataId$1 = "rescript-schema:String.refinements";

Expand Down Expand Up @@ -2041,7 +2025,7 @@ function typeFilter$6(_b, inputVar) {
return "typeof " + inputVar + "!==\"bigint\"";
}

var schema$6 = makePrimitiveSchema("Unknown", noop, typeFilter$6);
var schema$6 = makePrimitiveSchema("Unknown", invalidJson, typeFilter$6);

schema$6.n = (() => "BigInt");

Expand Down
Loading

2 comments on commit edae1ca

@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: edae1ca Previous: 90ab99c Ratio
Parse string 172073127 ops/sec (±0.12%) 811431552 ops/sec (±0.15%) 4.72
Serialize string 172202171 ops/sec (±0.08%) 812781945 ops/sec (±0.05%) 4.72
Advanced object schema factory 471522 ops/sec (±0.69%) 472293 ops/sec (±0.54%) 1.00
Parse advanced object 50312192 ops/sec (±1.49%) 56799894 ops/sec (±0.57%) 1.13
Assert advanced object - compile 163443066 ops/sec (±0.17%)
Assert advanced object 171536225 ops/sec (±0.22%) 171920805 ops/sec (±0.20%) 1.00
Create and parse advanced object 94114 ops/sec (±0.10%) 95083 ops/sec (±0.21%) 1.01
Parse advanced strict object 23907583 ops/sec (±0.41%) 25471962 ops/sec (±0.17%) 1.07
Assert advanced strict object 27432691 ops/sec (±1.81%) 30460141 ops/sec (±0.20%) 1.11
Serialize advanced object 49275908 ops/sec (±1.02%) 74797850 ops/sec (±0.32%) 1.52
Serialize advanced object - compile 145358151 ops/sec (±6.33%)

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

@github-actions
Copy link

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: edae1ca Previous: 90ab99c Ratio
Parse string 172073127 ops/sec (±0.12%) 811431552 ops/sec (±0.15%) 4.72
Serialize string 172202171 ops/sec (±0.08%) 812781945 ops/sec (±0.05%) 4.72
Serialize advanced object 49275908 ops/sec (±1.02%) 74797850 ops/sec (±0.32%) 1.52

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

Please sign in to comment.