From a5985b6a5273e268b6c157d42ece33d3535d8201 Mon Sep 17 00:00:00 2001 From: Dmitry Zakharov Date: Sat, 13 Jul 2024 18:16:38 +0400 Subject: [PATCH] Inline tag values in generated checks --- packages/tests/src/core/S_object_test.res | 2 +- packages/tests/src/core/S_tuple_test.res | 4 +-- packages/tests/src/core/S_union_test.res | 6 ++-- packages/tests/src/core/S_variant_test.res | 6 ++-- src/S_Core.bs.mjs | 22 ++++++------ src/S_Core.res | 42 +++++++++++++--------- 6 files changed, 45 insertions(+), 37 deletions(-) diff --git a/packages/tests/src/core/S_object_test.res b/packages/tests/src/core/S_object_test.res index c421d17a..314d64a2 100644 --- a/packages/tests/src/core/S_object_test.res +++ b/packages/tests/src/core/S_object_test.res @@ -1163,7 +1163,7 @@ module Compiled = { t->U.assertCompiledCode( ~schema, ~op=#Serialize, - `i=>{if(i["zoo"]!==e[0]){e[1](i["zoo"])}return {"tag":e[2],"FOO":i["foo"],"BAR":i["bar"],}}`, + `i=>{if(i["zoo"]!==1){e[0](i["zoo"])}return {"tag":e[1],"FOO":i["foo"],"BAR":i["bar"],}}`, ) }, ) diff --git a/packages/tests/src/core/S_tuple_test.res b/packages/tests/src/core/S_tuple_test.res index c71730af..a7b2143a 100644 --- a/packages/tests/src/core/S_tuple_test.res +++ b/packages/tests/src/core/S_tuple_test.res @@ -267,7 +267,7 @@ module Compiled = { let schema = S.tuple(_ => ()) // TODO: No need to do unit check ? - t->U.assertCompiledCode(~schema, ~op=#Serialize, `i=>{if(i!==e[0]){e[1](i)}return []}`) + t->U.assertCompiledCode(~schema, ~op=#Serialize, `i=>{if(i!==undefined){e[0](i)}return []}`) }) test( @@ -305,7 +305,7 @@ module Compiled = { t->U.assertCompiledCode( ~schema, ~op=#Serialize, - `i=>{if(i["zoo"]!==e[0]){e[1](i["zoo"])}return [e[2],i["foo"],i["bar"],]}`, + `i=>{if(i["zoo"]!==1){e[0](i["zoo"])}return [e[1],i["foo"],i["bar"],]}`, ) }, ) diff --git a/packages/tests/src/core/S_union_test.res b/packages/tests/src/core/S_union_test.res index 71a599ec..58c710ae 100644 --- a/packages/tests/src/core/S_union_test.res +++ b/packages/tests/src/core/S_union_test.res @@ -413,7 +413,7 @@ module Advanced = { t->U.assertCompiledCode( ~schema=shapeSchema, ~op=#Serialize, - `i=>{let v0,v1,v2,v3;try{if(i["TAG"]!==e[0]){e[1](i["TAG"])}v0={"kind":e[2],"radius":i["radius"],};if(!v0||v0.constructor!==Object){e[3](v0)}v1=v0}catch(e0){try{if(i["TAG"]!==e[4]){e[5](i["TAG"])}v2={"kind":e[6],"x":i["x"],};if(!v2||v2.constructor!==Object){e[7](v2)}v1=v2}catch(e1){try{if(i["TAG"]!==e[8]){e[9](i["TAG"])}v3={"kind":e[10],"x":i["x"],"y":i["y"],};if(!v3||v3.constructor!==Object){e[11](v3)}v1=v3}catch(e2){e[12]([e0,e1,e2,])}}}return v1}`, + `i=>{let v0,v1,v2,v3;try{if(i["TAG"]!=="Circle"){e[0](i["TAG"])}v0={"kind":e[1],"radius":i["radius"],};if(!v0||v0.constructor!==Object){e[2](v0)}v1=v0}catch(e0){try{if(i["TAG"]!=="Square"){e[3](i["TAG"])}v2={"kind":e[4],"x":i["x"],};if(!v2||v2.constructor!==Object){e[5](v2)}v1=v2}catch(e1){try{if(i["TAG"]!=="Triangle"){e[6](i["TAG"])}v3={"kind":e[7],"x":i["x"],"y":i["y"],};if(!v3||v3.constructor!==Object){e[8](v3)}v1=v3}catch(e2){e[9]([e0,e1,e2,])}}}return v1}`, ) }) } @@ -508,7 +508,7 @@ module CknittelBugReport = { t->U.assertCompiledCode( ~schema, ~op=#Serialize, - `i=>{let v2,v3,v6;try{let v0=i["_0"]["payload"]["a"],v1;if(i["TAG"]!==e[0]){e[1](i["TAG"])}if(v0!==void 0){v1=e[2](v0)}v2={"payload":{"a":v1,},};if(!v2||v2.constructor!==Object){e[3](v2)}v3=v2}catch(e0){try{let v4=i["_0"]["payload"]["b"],v5;if(i["TAG"]!==e[4]){e[5](i["TAG"])}if(v4!==void 0){v5=e[6](v4)}v6={"payload":{"b":v5,},};if(!v6||v6.constructor!==Object){e[7](v6)}v3=v6}catch(e1){e[8]([e0,e1,])}}return v3}`, + `i=>{let v2,v3,v6;try{let v0=i["_0"]["payload"]["a"],v1;if(i["TAG"]!=="A"){e[0](i["TAG"])}if(v0!==void 0){v1=e[1](v0)}v2={"payload":{"a":v1,},};if(!v2||v2.constructor!==Object){e[2](v2)}v3=v2}catch(e0){try{let v4=i["_0"]["payload"]["b"],v5;if(i["TAG"]!=="B"){e[3](i["TAG"])}if(v4!==void 0){v5=e[4](v4)}v6={"payload":{"b":v5,},};if(!v6||v6.constructor!==Object){e[5](v6)}v3=v6}catch(e1){e[6]([e0,e1,])}}return v3}`, ) let x = { @@ -605,7 +605,7 @@ module CrazyUnion = { t->U.assertCompiledCode( ~schema, ~op=#Serialize, - `i=>{let r0=i=>{let v5,v6,v12;try{let v0=i["_0"],v4=[];if(i["TAG"]!==e[0]){e[1](i["TAG"])}for(let v1=0;v1{let r0=i=>{let v5,v6,v12;try{let v0=i["_0"],v4=[];if(i["TAG"]!=="A"){e[0](i["TAG"])}for(let v1=0;v1 { t->U.assertCompiledCode( ~schema, ~op=#Serialize, - `i=>{if(i["TAG"]!==e[0]){e[1](i["TAG"])}return {"foo":i["_0"],}}`, + `i=>{if(i["TAG"]!=="Ok"){e[0](i["TAG"])}return {"foo":i["_0"],}}`, ) }) @@ -161,7 +161,7 @@ test("Compiled serialize code snapshot", t => { t->U.assertCompiledCode( ~schema, ~op=#Serialize, - `i=>{let v0=i["TAG"];if(v0!==e[0]){e[1](v0)}return i["_0"]}`, + `i=>{let v0=i["TAG"];if(v0!=="Ok"){e[0](v0)}return i["_0"]}`, ) }) @@ -180,7 +180,7 @@ test( t->U.assertCompiledCode( ~schema, ~op=#Serialize, - `i=>{let v0=e[2];if(i!==e[0]){e[1](i)}if(v0!==e[3]&&(!Array.isArray(v0)||v0.length!==2||v0[0]!==true||v0[1]!==12)){e[4](v0)}return v0}`, + `i=>{let v0=e[1];if(i!=="foo"){e[0](i)}if(v0!==e[2]&&(!Array.isArray(v0)||v0.length!==2||v0[0]!==true||v0[1]!==12)){e[3](v0)}return v0}`, ) }, ) diff --git a/src/S_Core.bs.mjs b/src/S_Core.bs.mjs index 90744d8a..f4c6077f 100644 --- a/src/S_Core.bs.mjs +++ b/src/S_Core.bs.mjs @@ -1426,13 +1426,13 @@ function serializeOperationBuilder$1(b, input, selfSchema, path) { } return ; } - var schema$1 = literal(definition); + var tagSchema = literal(definition); var itemInputVar = inputVar + outputPath; - ctx.d = ctx.d + ("if(" + itemInputVar + "!==" + ("e[" + (b.g.e.push(definition) - 1) + "]") + "){" + failWithArg(b, path + outputPath, (function (input) { + ctx.d = ctx.d + ("if(" + tagSchema.f(b, itemInputVar) + "){" + failWithArg(b, path + outputPath, (function (received) { return { TAG: "InvalidType", - expected: schema$1, - received: input + expected: tagSchema, + received: received }; }), itemInputVar) + "}"); }; @@ -1642,16 +1642,16 @@ function factory$3(schema, definer) { } return maybeOutputRef; } - var schema = literal(definition); - var constantVal = valuePath === "" ? input : val(b, inputVar + valuePath); - var constantVar = $$var(b, constantVal); - b.c = b.c + ("if(" + constantVar + "!==" + ("e[" + (b.g.e.push(definition) - 1) + "]") + "){" + failWithArg(b, path + valuePath, (function (input) { + var tagSchema = literal(definition); + var tagVal = valuePath === "" ? input : val(b, inputVar + valuePath); + var tagInputVar = $$var(b, tagVal); + b.c = b.c + ("if(" + tagSchema.f(b, tagInputVar) + "){" + failWithArg(b, path + valuePath, (function (received) { return { TAG: "InvalidType", - expected: schema, - received: input + expected: tagSchema, + received: received }; - }), constantVar) + "}"); + }), tagInputVar) + "}"); return 0; }; var output = definitionToValue(definition, ""); diff --git a/src/S_Core.res b/src/S_Core.res index 2d283396..747dd2d1 100644 --- a/src/S_Core.res +++ b/src/S_Core.res @@ -11,6 +11,10 @@ module Obj = { } module Stdlib = { + module Option = { + external unsafeUnwrap: option<'a> => 'a = "%identity" + } + module Type = { type t = [#undefined | #object | #boolean | #number | #bigint | #string | #symbol | #function] @@ -819,7 +823,6 @@ module Literal = { @inline let toString = literal => (literal->toInternal).string - // FIXME: let arrayFilterBuilder = (b, ~inputVar, ~literal) => { let items = (literal->toInternal).items->(Obj.magic: option => array) @@ -841,7 +844,6 @@ module Literal = { : "") ++ ")" } - // FIXME: let dictFilterBuilder = (b, ~inputVar, ~literal) => { let items = (literal->toInternal).items->(Obj.magic: option => dict) let fields = items->Js.Dict.keys @@ -2072,16 +2074,19 @@ module Object = { } } } else { - let value = definition->Definition.toConstant - let schema = literal(value) // FIXME: Use it more actively + let tag = definition->Definition.toConstant + let tagSchema = literal(tag) let itemInputVar = `${inputVar}${outputPath}` ctx.discriminantCode = ctx.discriminantCode ++ - `if(${itemInputVar}!==${b->B.embed(value)}){${b->B.failWithArg( + `if(${(tagSchema.maybeTypeFilter->Stdlib.Option.unsafeUnwrap)( + b, + ~inputVar=itemInputVar, + )}){${b->B.failWithArg( ~path=path->Path.concat(outputPath), - input => InvalidType({ - expected: schema, - received: input, + received => InvalidType({ + expected: tagSchema, + received, }), itemInputVar, )}}` @@ -2356,19 +2361,22 @@ module Variant = { } maybeOutputRef.contents } else { - let constant = definition->Definition.toConstant - let schema = literal(constant) // FIXME: Use it more actively - let constantVal = valuePath === "" ? input : b->B.val(`${inputVar}${valuePath}`) - let constantVar = b->B.Val.var(constantVal) + let tag = definition->Definition.toConstant + let tagSchema = literal(tag) + let tagVal = valuePath === "" ? input : b->B.val(`${inputVar}${valuePath}`) + let tagInputVar = b->B.Val.var(tagVal) b.code = b.code ++ - `if(${constantVar}!==${b->B.embed(constant)}){${b->B.failWithArg( + `if(${(tagSchema.maybeTypeFilter->Stdlib.Option.unsafeUnwrap)( + b, + ~inputVar=tagInputVar, + )}){${b->B.failWithArg( ~path=path->Path.concat(valuePath), - input => InvalidType({ - expected: schema, - received: input, + received => InvalidType({ + expected: tagSchema, + received, }), - constantVar, + tagInputVar, )}}` Unregistered }