From 7a4c43d12684020b6b2cbceca18b429dd20d0bac Mon Sep 17 00:00:00 2001 From: Andrew Paseltiner Date: Tue, 18 Jun 2024 10:07:02 -0400 Subject: [PATCH] Simplify collection parsing and explicitly mark variance of Maybe (#1338) --- ts/src/header-validator/maybe.ts | 2 +- ts/src/header-validator/validate.ts | 63 +++++++++++++---------------- 2 files changed, 30 insertions(+), 35 deletions(-) diff --git a/ts/src/header-validator/maybe.ts b/ts/src/header-validator/maybe.ts index 3db94c5595..f0b6f6838f 100644 --- a/ts/src/header-validator/maybe.ts +++ b/ts/src/header-validator/maybe.ts @@ -1,4 +1,4 @@ -export class Maybe { +export class Maybe { static readonly None = new Maybe() static some(this: void, t: T): Maybe { diff --git a/ts/src/header-validator/validate.ts b/ts/src/header-validator/validate.ts index c7faa67a9b..950ae56b28 100644 --- a/ts/src/header-validator/validate.ts +++ b/ts/src/header-validator/validate.ts @@ -168,26 +168,26 @@ export enum ItemErrorAction { earlyExit, } -function isCollection

( +function collection( + out: Coll, vs: Iterable<[P, V]>, ctx: C, - f: CtxFunc>, + f: (out: Coll, v: V, p: P) => Maybe, itemErrorAction: ItemErrorAction = ItemErrorAction.reportButKeepGoing -): boolean { +): Maybe { let ok = true - for (const [c, v] of vs) { - let itemOk = false - ctx.scope(c, () => f([c, v], ctx).peek(() => (itemOk = true))) + for (const [p, v] of vs) { + const itemOk = ctx.scope(p, () => f(out, v, p).value !== undefined) if (!itemOk) { if (itemErrorAction === ItemErrorAction.earlyExit) { - return false + return Maybe.None } if (itemErrorAction === ItemErrorAction.reportButKeepGoing) { ok = false } } } - return ok + return ok ? Maybe.some(out) : Maybe.None } export function array( @@ -196,13 +196,12 @@ export function array( f: CtxFunc>, itemErrorAction: ItemErrorAction = ItemErrorAction.reportButKeepGoing ): Maybe { - return Maybe.some(new Array()).filter((arr) => - isCollection( - vs, - ctx, - ([, v]) => f(v, ctx).peek((v) => arr.push(v)), - itemErrorAction - ) + return collection( + new Array(), + vs, + ctx, + (arr, v) => f(v, ctx).peek((v) => arr.push(v)), + itemErrorAction ) } @@ -212,22 +211,20 @@ export function set( f: CtxFunc>, requireDistinct: boolean = false ): Maybe> { - return Maybe.some(new Set()).filter((set) => - isCollection(vs, ctx, ([, v]) => - f(v, ctx).filter((v) => { - if (set.has(v)) { - const msg = `duplicate value ${v}` - if (requireDistinct) { - ctx.error(msg) - return false - } - ctx.warning(msg) - } else { - set.add(v) + return collection(new Set(), vs, ctx, (set, v) => + f(v, ctx).filter((v) => { + if (set.has(v)) { + const msg = `duplicate value ${v}` + if (requireDistinct) { + ctx.error(msg) + return false } - return true - }) - ) + ctx.warning(msg) + } else { + set.add(v) + } + return true + }) ) } @@ -236,10 +233,8 @@ export function keyValues( ctx: C, f: CtxFunc> ): Maybe> { - return Maybe.some(new Map()).filter((map) => - isCollection(vs, ctx, ([key, v]) => - f([key, v], ctx).peek((v) => map.set(key, v)) - ) + return collection(new Map(), vs, ctx, (map, v, key) => + f([key, v], ctx).peek((v) => map.set(key, v)) ) }