From dcd7fe52c543b614f1b54952ee8416d1d4cf0156 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Thu, 17 Mar 2022 19:44:57 -0400 Subject: [PATCH 1/2] Fast unions --- coverage.svg | 6 +++++- deno/lib/types.ts | 42 ++++++++++++++++++++++++++++++++---------- src/types.ts | 42 ++++++++++++++++++++++++++++++++---------- 3 files changed, 69 insertions(+), 21 deletions(-) diff --git a/coverage.svg b/coverage.svg index 16e49a97b..66a0c9f15 100644 --- a/coverage.svg +++ b/coverage.svg @@ -1 +1,5 @@ -Coverage: 96.16%Coverage96.16% \ No newline at end of file +<<<<<<< HEAD +Coverage: 96.16%Coverage96.16% +======= +Coverage: 96.1%Coverage96.1% +>>>>>>> 3b6802c (Fast unions) diff --git a/deno/lib/types.ts b/deno/lib/types.ts index caf9c014b..0b587355b 100644 --- a/deno/lib/types.ts +++ b/deno/lib/types.ts @@ -2,6 +2,7 @@ import { errorUtil } from "./helpers/errorUtil.ts"; import { addIssueToContext, AsyncParseReturnType, + DIRTY, getParsedType, INVALID, isAborted, @@ -1875,23 +1876,44 @@ export class ZodUnion extends ZodType< }) ).then(handleResults); } else { - const optionResults = options.map((option) => { + let dirty: undefined | { result: DIRTY; ctx: ParseContext } = + undefined; + const issues: ZodIssue[][] = []; + for (const option of options) { const childCtx: ParseContext = { ...ctx, issues: [], parent: null, }; - return { - result: option._parseSync({ - data: ctx.data, - path: ctx.path, - parent: childCtx, - }), - ctx: childCtx, - }; + const result = option._parseSync({ + data: ctx.data, + path: ctx.path, + parent: childCtx, + }); + + if (result.status === "valid") { + return result; + } else if (result.status === "dirty" && !dirty) { + dirty = { result, ctx: childCtx }; + } + + if (childCtx.issues.length) { + issues.push(childCtx.issues); + } + } + + if (dirty) { + ctx.issues.push(...dirty.ctx.issues); + return dirty.result; + } + + const unionErrors = issues.map((issues) => new ZodError(issues)); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_union, + unionErrors, }); - return handleResults(optionResults); + return INVALID; } } diff --git a/src/types.ts b/src/types.ts index b3b7c1df2..6538289ba 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,6 +2,7 @@ import { errorUtil } from "./helpers/errorUtil"; import { addIssueToContext, AsyncParseReturnType, + DIRTY, getParsedType, INVALID, isAborted, @@ -1875,23 +1876,44 @@ export class ZodUnion extends ZodType< }) ).then(handleResults); } else { - const optionResults = options.map((option) => { + let dirty: undefined | { result: DIRTY; ctx: ParseContext } = + undefined; + const issues: ZodIssue[][] = []; + for (const option of options) { const childCtx: ParseContext = { ...ctx, issues: [], parent: null, }; - return { - result: option._parseSync({ - data: ctx.data, - path: ctx.path, - parent: childCtx, - }), - ctx: childCtx, - }; + const result = option._parseSync({ + data: ctx.data, + path: ctx.path, + parent: childCtx, + }); + + if (result.status === "valid") { + return result; + } else if (result.status === "dirty" && !dirty) { + dirty = { result, ctx: childCtx }; + } + + if (childCtx.issues.length) { + issues.push(childCtx.issues); + } + } + + if (dirty) { + ctx.issues.push(...dirty.ctx.issues); + return dirty.result; + } + + const unionErrors = issues.map((issues) => new ZodError(issues)); + addIssueToContext(ctx, { + code: ZodIssueCode.invalid_union, + unionErrors, }); - return handleResults(optionResults); + return INVALID; } } From 555ff2258b5e94079572e26ea0a0db626557c7bd Mon Sep 17 00:00:00 2001 From: Colin McDonnell Date: Fri, 18 Mar 2022 01:12:48 -0700 Subject: [PATCH 2/2] Update coverage --- deno/lib/types.ts | 1 + src/types.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/deno/lib/types.ts b/deno/lib/types.ts index 0b587355b..bec55020f 100644 --- a/deno/lib/types.ts +++ b/deno/lib/types.ts @@ -1850,6 +1850,7 @@ export class ZodUnion extends ZodType< const unionErrors = results.map( (result) => new ZodError(result.ctx.issues) ); + addIssueToContext(ctx, { code: ZodIssueCode.invalid_union, unionErrors, diff --git a/src/types.ts b/src/types.ts index 6538289ba..29db38b2a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1850,6 +1850,7 @@ export class ZodUnion extends ZodType< const unionErrors = results.map( (result) => new ZodError(result.ctx.issues) ); + addIssueToContext(ctx, { code: ZodIssueCode.invalid_union, unionErrors,