Skip to content

Commit

Permalink
Merge pull request #1026 from tmcw/fast-unions
Browse files Browse the repository at this point in the history
Fast unions
  • Loading branch information
colinhacks authored Mar 18, 2022
2 parents 96d3c34 + 555ff22 commit 5b46d88
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 21 deletions.
6 changes: 5 additions & 1 deletion coverage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 33 additions & 10 deletions deno/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { errorUtil } from "./helpers/errorUtil.ts";
import {
addIssueToContext,
AsyncParseReturnType,
DIRTY,
getParsedType,
INVALID,
isAborted,
Expand Down Expand Up @@ -1849,6 +1850,7 @@ export class ZodUnion<T extends ZodUnionOptions> extends ZodType<
const unionErrors = results.map(
(result) => new ZodError(result.ctx.issues)
);

addIssueToContext(ctx, {
code: ZodIssueCode.invalid_union,
unionErrors,
Expand All @@ -1875,23 +1877,44 @@ export class ZodUnion<T extends ZodUnionOptions> extends ZodType<
})
).then(handleResults);
} else {
const optionResults = options.map((option) => {
let dirty: undefined | { result: DIRTY<any>; 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;
}
}

Expand Down
43 changes: 33 additions & 10 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { errorUtil } from "./helpers/errorUtil";
import {
addIssueToContext,
AsyncParseReturnType,
DIRTY,
getParsedType,
INVALID,
isAborted,
Expand Down Expand Up @@ -1849,6 +1850,7 @@ export class ZodUnion<T extends ZodUnionOptions> extends ZodType<
const unionErrors = results.map(
(result) => new ZodError(result.ctx.issues)
);

addIssueToContext(ctx, {
code: ZodIssueCode.invalid_union,
unionErrors,
Expand All @@ -1875,23 +1877,44 @@ export class ZodUnion<T extends ZodUnionOptions> extends ZodType<
})
).then(handleResults);
} else {
const optionResults = options.map((option) => {
let dirty: undefined | { result: DIRTY<any>; 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;
}
}

Expand Down

0 comments on commit 5b46d88

Please sign in to comment.