Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

S.compile #91

Merged
merged 2 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions IDEAS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,29 @@ let trimContract: S.contract<string => string> = S.contract(s => {

## v9

- Add S.reverse
- Add S.compile
- 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

## v10

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

## v???
Expand Down
138 changes: 74 additions & 64 deletions src/S_Core.bs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,14 @@ function transform(b, input, operation) {
}

function raise(b, code, path) {
throw new RescriptSchemaError(code, b.g.o, path);
var operation = b.g.o;
throw new RescriptSchemaError(code, operation & 8 ? "Assert" : (
operation & 1 ? (
operation & 2 ? "ParseAsync" : "Parse"
) : (
operation & 4 ? "SerializeToJson" : "SerializeToUnknown"
)
), path);
}

function embedSyncOperation(b, input, fn) {
Expand All @@ -238,7 +245,7 @@ function embedSyncOperation(b, input, fn) {
}

function embedAsyncOperation(b, input, fn) {
if (b.g.o !== "ParseAsync") {
if (!(b.g.o & 2)) {
raise(b, "UnexpectedAsync", "");
}
var val = embedSyncOperation(b, input, (function (v) {
Expand Down Expand Up @@ -277,7 +284,7 @@ function effectCtx(b, selfSchema, path) {
}

function registerInvalidJson(b, selfSchema, path) {
if (b.g.o === "SerializeToJson") {
if (b.g.o & 4) {
return raise(b, {
TAG: "InvalidJsonSchema",
_0: selfSchema
Expand Down Expand Up @@ -363,7 +370,7 @@ function parseWithTypeCheck(b, schema, input, path) {
if (typeFilter === undefined) {
return schema.b(b, input, schema, path);
}
if (!(schema.t.TAG === "Literal" || b.g.o !== "SerializeToJson" && b.g.o !== "SerializeToUnknown")) {
if (!(schema.t.TAG === "Literal" || b.g.o & 1)) {
return schema.b(b, input, schema, path);
}
b.c = b.c + typeFilterCode(b, typeFilter, schema, input, path);
Expand All @@ -381,7 +388,7 @@ function noopOperation(i) {
return i;
}

function build(builder, schema, operation, finalizer) {
function compile(builder, schema, operation) {
var b = {
c: "",
l: "",
Expand All @@ -398,17 +405,48 @@ function build(builder, schema, operation, finalizer) {
a: false
};
var output = builder(b, input, schema, "");
schema.i = output.a;
if (b.l !== "") {
b.c = "let " + b.l + ";" + b.c;
}
var output$1 = finalizer(b, schema, input, output);
if (b.c === "" && output$1 === input) {
if (operation & 1 || schema.t.TAG === "Literal") {
var typeFilter = schema.f;
if (typeFilter !== undefined) {
b.c = typeFilterCode(b, typeFilter, schema, input, "") + b.c;
}

}
if (b.c === "" && output === input && !(operation & 8)) {
return noopOperation;
}
var inlinedFunction = "i=>{" + b.c + "return " + inline(b, output$1) + "}";
var inlinedOutput = operation & 8 ? "void 0" : (
operation & 2 && !output.a ? "Promise.resolve(" + inline(b, output) + ")" : inline(b, output)
);
var inlinedFunction = "i=>{" + b.c + "return " + inlinedOutput + "}";
return new Function("e", "s", "return " + inlinedFunction)(b.g.e, symbol);
}

function compile$1(schema, input, output, typeValidation) {
var operation = 0;
switch (output) {
case "Output" :
case "Unknown" :
break;
case "Assert" :
operation = operation | 8;
break;
case "Json" :
case "JsonString" :
operation = operation | 4;
break;

}
if (typeValidation) {
operation = operation | 1;
}
return compile(schema.b, schema, operation);
}

function toSelf() {
return this;
}
Expand Down Expand Up @@ -625,19 +663,29 @@ function parse(any) {
return parseInternal(any);
}

function isAsyncSchemaFinalizer(b, schema, input, output) {
schema.i = output.a;
b.c = "";
return input;
}

function isAsyncParse(schema) {
var v = schema.i;
if (typeof v === "boolean") {
return v;
}
try {
build(schema.b, schema, "ParseAsync", isAsyncSchemaFinalizer);
var b = {
c: "",
l: "",
a: false,
g: {
v: -1,
o: 2,
e: []
}
};
var input = {
v: "i",
s: b,
a: false
};
var output = schema.b(b, input, schema, "");
schema.i = output.a;
return schema.i;
}
catch (raw_exn){
Expand Down Expand Up @@ -793,70 +841,31 @@ function parseJsonStringWith(jsonString, schema) {
}
}

function parseFinalizer(b, schema, input, output) {
var typeFilter = schema.f;
if (typeFilter !== undefined) {
b.c = typeFilterCode(b, typeFilter, schema, input, "") + b.c;
}
schema.i = false;
return output;
}

function initialParseOrRaise(unknown) {
var schema = this;
var operation = build(schema.b, schema, "Parse", parseFinalizer);
var operation = compile(schema.b, schema, 1);
schema.parseOrThrow = operation;
return operation(unknown);
}

function parseAsyncFinalizer(b, schema, input, output) {
var typeFilter = schema.f;
if (typeFilter !== undefined) {
b.c = typeFilterCode(b, typeFilter, schema, input, "") + b.c;
}
schema.i = output.a;
if (output.a) {
return output;
} else {
return asyncVal(b, "Promise.resolve(" + inline(b, output) + ")");
}
}

function serializeFinalizer(b, schema, input, output) {
var typeFilter = schema.f;
if (typeFilter !== undefined && schema.t.TAG === "Literal") {
b.c = typeFilterCode(b, typeFilter, schema, input, "") + b.c;
}
return output;
}

function initialParseAsyncOrRaise(unknown) {
var schema = this;
var operation = build(schema.b, schema, "ParseAsync", parseAsyncFinalizer);
var operation = compile(schema.b, schema, 3);
schema.a = operation;
return operation(unknown);
}

function assertFinalizer(b, schema, input, param) {
var typeFilter = schema.f;
if (typeFilter !== undefined) {
b.c = typeFilterCode(b, typeFilter, schema, input, "") + b.c;
}
schema.i = false;
return val(b, "void 0");
}

function initialAssertOrRaise(unknown) {
var schema = this;
var operation = build(schema.b, schema, "Assert", assertFinalizer);
var operation = compile(schema.b, schema, 9);
schema.assert = operation;
return operation(unknown);
}

function initialSerializeToUnknownOrRaise(unknown) {
var schema = this;
var reversed = schema.r();
var operation = build(reversed.b, reversed, "SerializeToUnknown", serializeFinalizer);
var operation = compile(reversed.b, reversed, 0);
schema.serializeOrThrow = operation;
return operation(unknown);
}
Expand All @@ -870,7 +879,7 @@ function initialSerializeOrRaise(unknown) {
}, "SerializeToJson", "");
}
var reversed = schema.r();
var operation = build(reversed.b, reversed, "SerializeToJson", serializeFinalizer);
var operation = compile(reversed.b, reversed, 4);
schema.serializeToJsonOrThrow = operation;
return operation(unknown);
}
Expand Down Expand Up @@ -1218,7 +1227,7 @@ function makeBuilder(isNullInput, isNullOutput) {
var childSchemaTag = childSchema.t.TAG;
var bb = scope(b);
var itemInput;
if ((b.g.o === "SerializeToJson" || b.g.o === "SerializeToUnknown") && (childSchema.t === "Unknown" || childSchemaTag === "Option" || childSchemaTag === "Literal" && childSchema.t._0.value === (void 0))) {
if (!(b.g.o & 1) && (childSchema.t === "Unknown" || childSchemaTag === "Option" || childSchemaTag === "Literal" && childSchema.t._0.value === (void 0))) {
var value = Caml_option.valFromOption;
itemInput = val(bb, "e[" + (bb.g.e.push(value) - 1) + "](" + $$var(b, input) + ")");
} else {
Expand Down Expand Up @@ -1387,7 +1396,7 @@ function builder$1(b, input, selfSchema, path) {
var path$1 = path + itemPath;
var isLiteral = schema$1.t.TAG === "Literal";
var typeFilter = schema$1.f;
if (typeFilter !== undefined && (isLiteral || b.g.o !== "SerializeToJson" && b.g.o !== "SerializeToUnknown")) {
if (typeFilter !== undefined && (isLiteral || b.g.o & 1)) {
b.c = b.c + typeFilterCode(b, typeFilter, schema$1, itemInput, path$1);
}
if (isObject && schema$1.d) {
Expand All @@ -1412,7 +1421,7 @@ function builder$1(b, input, selfSchema, path) {
}
}
}
if (!(isObject && selfSchema.t.unknownKeys === "Strict" && b.g.o !== "SerializeToJson" && b.g.o !== "SerializeToUnknown")) {
if (!(isObject && selfSchema.t.unknownKeys === "Strict" && b.g.o & 1)) {
return ;
}
var key = allocateVal(b);
Expand Down Expand Up @@ -1885,7 +1894,7 @@ function factory$5(schema, spaceOpt) {
var reversed = schema.r();
return makeReverseSchema(reversed.n, reversed.t, reversed.m, (function (b, input, param, path) {
var prevOperation = b.g.o;
b.g.o = "SerializeToJson";
b.g.o = prevOperation | 4;
if (reversed.t.TAG === "Option") {
raise(b, {
TAG: "InvalidJsonSchema",
Expand Down Expand Up @@ -1959,7 +1968,7 @@ function parse$1(b, schemas, path, input, output) {
try {
var bb = scope(b);
var itemOutput = schema.b(bb, input, schema, "");
if (isMultiple && (b.g.o === "SerializeToJson" || b.g.o === "SerializeToUnknown")) {
if (isMultiple && !(b.g.o & 1)) {
var reversed = schema.r();
var typeFilter = reversed.f;
if (typeFilter !== undefined) {
Expand Down Expand Up @@ -3149,6 +3158,7 @@ export {
custom ,
refine ,
variant ,
compile$1 as compile,
parseWith ,
parseAnyWith ,
parseJsonStringWith ,
Expand Down
Loading
Loading