diff --git a/README.md b/README.md index d40430ca1..6c0b2ef4a 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ * [@mondrian-framework/model](https://mondrianframework.com) * [myzod](https://github.com/davidmdm/myzod) * [ok-computer](https://github.com/richardscarrott/ok-computer) +* [pure-parse](https://github.com/johannes-lindgren/pure-parse) * [purify-ts](https://github.com/gigobyte/purify) * [parse-dont-validate](https://github.com/Packer-Man/parse-dont-validate) * [r-assign](https://github.com/micnic/r-assign) diff --git a/cases/index.ts b/cases/index.ts index 9943c7aac..b0878e07d 100644 --- a/cases/index.ts +++ b/cases/index.ts @@ -17,6 +17,7 @@ export const cases = [ 'myzod', 'ok-computer', 'parse-dont-validate', + 'pure-parse', 'purify-ts', 'r-assign', 'rescript-schema', diff --git a/cases/pure-parse.ts b/cases/pure-parse.ts new file mode 100644 index 000000000..6b7fb135b --- /dev/null +++ b/cases/pure-parse.ts @@ -0,0 +1,157 @@ +import { createCase } from '../benchmarks'; +import { + object, + objectCompiled, + objectGuard, + objectGuardCompiled, + parseString, + parseNumber, + parseBoolean, + type Parser, + type Guard, + isNumber, + isString, + isBoolean, + objectStrict, + objectStrictCompiled, +} from 'pure-parse'; + +/** + * Given a PureParse parser, return a new parser that throws an error if parsing fails, and returns the value if parsing succeeds. + * @param parse + * @returns a parser that is compatible with `createCase` + */ +const tryParse = + (parse: Parser) => + (data: unknown): T => { + const res = parse(data); + if (res.tag === 'failure') { + throw new Error('parsing failed'); + } else { + return res.value; + } + }; + +/** + * Given a PureParse guard, return a new guard that throws an error if parsing fails, and returns the value if parsing succeeds. + * @param guard + * @returns a parser that is compatible with `createCase` + */ +const tryGuard = + (guard: Guard) => + (data: unknown): true => { + const isT = guard(data); + if (!isT) { + throw new Error('validation failed'); + } else { + return true; + } + }; + +createCase('pure-parse (JIT compiled)', 'parseSafe', () => + tryParse( + objectCompiled({ + number: parseNumber, + negNumber: parseNumber, + maxNumber: parseNumber, + string: parseString, + longString: parseString, + boolean: parseBoolean, + deeplyNested: objectCompiled({ + foo: parseString, + num: parseNumber, + bool: parseBoolean, + }), + }), + ), +); + +createCase('pure-parse', 'parseSafe', () => + tryParse( + object({ + number: parseNumber, + negNumber: parseNumber, + maxNumber: parseNumber, + string: parseString, + longString: parseString, + boolean: parseBoolean, + deeplyNested: object({ + foo: parseString, + num: parseNumber, + bool: parseBoolean, + }), + }), + ), +); + +createCase('pure-parse', 'parseStrict', () => + tryParse( + objectStrict({ + number: parseNumber, + negNumber: parseNumber, + maxNumber: parseNumber, + string: parseString, + longString: parseString, + boolean: parseBoolean, + deeplyNested: objectStrict({ + foo: parseString, + num: parseNumber, + bool: parseBoolean, + }), + }), + ), +); + +createCase('pure-parse (JIT compiled)', 'parseStrict', () => + tryParse( + objectStrictCompiled({ + number: parseNumber, + negNumber: parseNumber, + maxNumber: parseNumber, + string: parseString, + longString: parseString, + boolean: parseBoolean, + deeplyNested: objectStrictCompiled({ + foo: parseString, + num: parseNumber, + bool: parseBoolean, + }), + }), + ), +); + +createCase('pure-parse (JIT compiled)', 'assertLoose', () => + tryGuard( + objectGuardCompiled({ + number: isNumber, + negNumber: isNumber, + maxNumber: isNumber, + string: isString, + longString: isString, + boolean: isBoolean, + deeplyNested: objectGuardCompiled({ + foo: isString, + num: isNumber, + bool: isBoolean, + }), + }), + ), +); + +createCase('pure-parse', 'assertLoose', () => + tryGuard( + objectGuard({ + number: isNumber, + negNumber: isNumber, + maxNumber: isNumber, + string: isString, + longString: isString, + boolean: isBoolean, + deeplyNested: objectGuard({ + foo: isString, + num: isNumber, + bool: isBoolean, + }), + }), + ), +); diff --git a/package-lock.json b/package-lock.json index fbdaab34c..782f53307 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,6 +47,7 @@ "ok-computer": "1.0.4", "parse-dont-validate": "4.0.0", "preact": "10.25.0", + "pure-parse": "0.0.0-beta.7", "purify-ts": "2.1.0", "r-assign": "1.9.0", "reflect-metadata": "0.2.2", @@ -8922,6 +8923,15 @@ "node": ">=6" } }, + "node_modules/pure-parse": { + "version": "0.0.0-beta.7", + "resolved": "https://registry.npmjs.org/pure-parse/-/pure-parse-0.0.0-beta.7.tgz", + "integrity": "sha512-N4oek21bYr6ruPFYX3KFkFqJwVbr5SFpia0mItuEMQCZQFomMfp8t2tmtVYjzK/3sauUPNSKCwomtHdK6wKnow==", + "license": "MIT", + "workspaces": [ + "packages/*" + ] + }, "node_modules/pure-rand": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", @@ -17805,6 +17815,11 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" }, + "pure-parse": { + "version": "0.0.0-beta.7", + "resolved": "https://registry.npmjs.org/pure-parse/-/pure-parse-0.0.0-beta.7.tgz", + "integrity": "sha512-N4oek21bYr6ruPFYX3KFkFqJwVbr5SFpia0mItuEMQCZQFomMfp8t2tmtVYjzK/3sauUPNSKCwomtHdK6wKnow==" + }, "pure-rand": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", diff --git a/package.json b/package.json index 4ab2e9063..8701bd87b 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "ok-computer": "1.0.4", "parse-dont-validate": "4.0.0", "preact": "10.25.0", + "pure-parse": "0.0.0-beta.7", "purify-ts": "2.1.0", "r-assign": "1.9.0", "reflect-metadata": "0.2.2", diff --git a/test/benchmarks.test.ts b/test/benchmarks.test.ts index c3d1d5a21..18bec2ee5 100644 --- a/test/benchmarks.test.ts +++ b/test/benchmarks.test.ts @@ -21,6 +21,7 @@ import '../cases/mondrian-framework'; import '../cases/myzod'; import '../cases/ok-computer'; import '../cases/parse-dont-validate'; +import '../cases/pure-parse'; import '../cases/purify-ts'; import '../cases/r-assign'; import '../cases/rescript-schema';