From a192473e304b4ca4c2b8b1264f3704fce37c776e Mon Sep 17 00:00:00 2001 From: Michael Arnaldi Date: Sat, 24 Feb 2024 19:56:28 +0100 Subject: [PATCH 1/2] Fix ConfigError `_tag` (#2206) --- .changeset/sharp-bears-sing.md | 5 +++ packages/effect/src/ConfigError.ts | 13 ++++--- packages/effect/src/internal/configError.ts | 41 +++++++++++---------- 3 files changed, 33 insertions(+), 26 deletions(-) create mode 100644 .changeset/sharp-bears-sing.md diff --git a/.changeset/sharp-bears-sing.md b/.changeset/sharp-bears-sing.md new file mode 100644 index 00000000000..e2c4b4beb99 --- /dev/null +++ b/.changeset/sharp-bears-sing.md @@ -0,0 +1,5 @@ +--- +"effect": minor +--- + +Fix ConfigError `_tag`, with the previous implementation catching the `ConfigError` with `Effect.catchTag` would show `And`, `Or`, etc. diff --git a/packages/effect/src/ConfigError.ts b/packages/effect/src/ConfigError.ts index cdd87b40a5e..ee84fb23b15 100644 --- a/packages/effect/src/ConfigError.ts +++ b/packages/effect/src/ConfigError.ts @@ -39,6 +39,7 @@ export declare namespace ConfigError { * @category models */ export interface Proto { + readonly _tag: "ConfigError" readonly [ConfigErrorTypeId]: ConfigErrorTypeId } @@ -72,7 +73,7 @@ export interface ConfigErrorReducer { * @category models */ export interface And extends ConfigError.Proto { - readonly _tag: "And" + readonly _op: "And" readonly left: ConfigError readonly right: ConfigError } @@ -82,7 +83,7 @@ export interface And extends ConfigError.Proto { * @category models */ export interface Or extends ConfigError.Proto { - readonly _tag: "Or" + readonly _op: "Or" readonly left: ConfigError readonly right: ConfigError } @@ -92,7 +93,7 @@ export interface Or extends ConfigError.Proto { * @category models */ export interface InvalidData extends ConfigError.Proto { - readonly _tag: "InvalidData" + readonly _op: "InvalidData" readonly path: Array readonly message: string } @@ -102,7 +103,7 @@ export interface InvalidData extends ConfigError.Proto { * @category models */ export interface MissingData extends ConfigError.Proto { - readonly _tag: "MissingData" + readonly _op: "MissingData" readonly path: Array readonly message: string } @@ -112,7 +113,7 @@ export interface MissingData extends ConfigError.Proto { * @category models */ export interface SourceUnavailable extends ConfigError.Proto { - readonly _tag: "SourceUnavailable" + readonly _op: "SourceUnavailable" readonly path: Array readonly message: string readonly cause: Cause.Cause @@ -123,7 +124,7 @@ export interface SourceUnavailable extends ConfigError.Proto { * @category models */ export interface Unsupported extends ConfigError.Proto { - readonly _tag: "Unsupported" + readonly _op: "Unsupported" readonly path: Array readonly message: string } diff --git a/packages/effect/src/internal/configError.ts b/packages/effect/src/internal/configError.ts index b034139bfd7..29d17328cd7 100644 --- a/packages/effect/src/internal/configError.ts +++ b/packages/effect/src/internal/configError.ts @@ -16,13 +16,14 @@ export const ConfigErrorTypeId: ConfigError.ConfigErrorTypeId = Symbol.for( /** @internal */ export const proto = { + _tag: "ConfigError", [ConfigErrorTypeId]: ConfigErrorTypeId } /** @internal */ export const And = (self: ConfigError.ConfigError, that: ConfigError.ConfigError): ConfigError.ConfigError => { const error = Object.create(proto) - error._tag = OpCodes.OP_AND + error._op = OpCodes.OP_AND error.left = self error.right = that Object.defineProperty(error, "toString", { @@ -37,7 +38,7 @@ export const And = (self: ConfigError.ConfigError, that: ConfigError.ConfigError /** @internal */ export const Or = (self: ConfigError.ConfigError, that: ConfigError.ConfigError): ConfigError.ConfigError => { const error = Object.create(proto) - error._tag = OpCodes.OP_OR + error._op = OpCodes.OP_OR error.left = self error.right = that Object.defineProperty(error, "toString", { @@ -56,7 +57,7 @@ export const InvalidData = ( options: ConfigError.Options = { pathDelim: "." } ): ConfigError.ConfigError => { const error = Object.create(proto) - error._tag = OpCodes.OP_INVALID_DATA + error._op = OpCodes.OP_INVALID_DATA error.path = path error.message = message Object.defineProperty(error, "toString", { @@ -76,7 +77,7 @@ export const MissingData = ( options: ConfigError.Options = { pathDelim: "." } ): ConfigError.ConfigError => { const error = Object.create(proto) - error._tag = OpCodes.OP_MISSING_DATA + error._op = OpCodes.OP_MISSING_DATA error.path = path error.message = message Object.defineProperty(error, "toString", { @@ -97,7 +98,7 @@ export const SourceUnavailable = ( options: ConfigError.Options = { pathDelim: "." } ): ConfigError.ConfigError => { const error = Object.create(proto) - error._tag = OpCodes.OP_SOURCE_UNAVAILABLE + error._op = OpCodes.OP_SOURCE_UNAVAILABLE error.path = path error.message = message error.cause = cause @@ -118,7 +119,7 @@ export const Unsupported = ( options: ConfigError.Options = { pathDelim: "." } ): ConfigError.ConfigError => { const error = Object.create(proto) - error._tag = OpCodes.OP_UNSUPPORTED + error._op = OpCodes.OP_UNSUPPORTED error.path = path error.message = message Object.defineProperty(error, "toString", { @@ -135,26 +136,26 @@ export const Unsupported = ( export const isConfigError = (u: unknown): u is ConfigError.ConfigError => hasProperty(u, ConfigErrorTypeId) /** @internal */ -export const isAnd = (self: ConfigError.ConfigError): self is ConfigError.And => self._tag === OpCodes.OP_AND +export const isAnd = (self: ConfigError.ConfigError): self is ConfigError.And => self._op === OpCodes.OP_AND /** @internal */ -export const isOr = (self: ConfigError.ConfigError): self is ConfigError.Or => self._tag === OpCodes.OP_OR +export const isOr = (self: ConfigError.ConfigError): self is ConfigError.Or => self._op === OpCodes.OP_OR /** @internal */ export const isInvalidData = (self: ConfigError.ConfigError): self is ConfigError.InvalidData => - self._tag === OpCodes.OP_INVALID_DATA + self._op === OpCodes.OP_INVALID_DATA /** @internal */ export const isMissingData = (self: ConfigError.ConfigError): self is ConfigError.MissingData => - self._tag === OpCodes.OP_MISSING_DATA + self._op === OpCodes.OP_MISSING_DATA /** @internal */ export const isSourceUnavailable = (self: ConfigError.ConfigError): self is ConfigError.SourceUnavailable => - self._tag === OpCodes.OP_SOURCE_UNAVAILABLE + self._op === OpCodes.OP_SOURCE_UNAVAILABLE /** @internal */ export const isUnsupported = (self: ConfigError.ConfigError): self is ConfigError.Unsupported => - self._tag === OpCodes.OP_UNSUPPORTED + self._op === OpCodes.OP_UNSUPPORTED /** @internal */ export const prefixed: { @@ -164,7 +165,7 @@ export const prefixed: { (prefix: ReadonlyArray) => (self: ConfigError.ConfigError) => ConfigError.ConfigError, (self: ConfigError.ConfigError, prefix: ReadonlyArray) => ConfigError.ConfigError >(2, (self, prefix) => { - switch (self._tag) { + switch (self._op) { case OpCodes.OP_AND: { return And(prefixed(self.left, prefix), prefixed(self.right, prefix)) } @@ -201,12 +202,12 @@ type ConfigErrorCase = AndCase | OrCase /** @internal */ interface AndCase { - readonly _tag: "AndCase" + readonly _op: "AndCase" } /** @internal */ interface OrCase { - readonly _tag: "OrCase" + readonly _op: "OrCase" } /** @internal */ @@ -218,17 +219,17 @@ export const reduceWithContext = dual< const output: Array> = [] while (input.length > 0) { const error = input.pop()! - switch (error._tag) { + switch (error._op) { case OpCodes.OP_AND: { input.push(error.right) input.push(error.left) - output.push(Either.left({ _tag: "AndCase" })) + output.push(Either.left({ _op: "AndCase" })) break } case OpCodes.OP_OR: { input.push(error.right) input.push(error.left) - output.push(Either.left({ _tag: "OrCase" })) + output.push(Either.left({ _op: "OrCase" })) break } case OpCodes.OP_INVALID_DATA: { @@ -252,9 +253,9 @@ export const reduceWithContext = dual< const accumulator: Array = [] while (output.length > 0) { const either = output.pop()! - switch (either._tag) { + switch (either._op) { case "Left": { - switch (either.left._tag) { + switch (either.left._op) { case "AndCase": { const left = accumulator.pop()! const right = accumulator.pop()! From 52ec4ca301dcc9afdb2e7062872d421dc7b554be Mon Sep 17 00:00:00 2001 From: Khraks Mamtsov Date: Tue, 27 Feb 2024 11:40:50 +0100 Subject: [PATCH 2/2] Changing the `HaltStrategy.match` function signature (#2202) Co-authored-by: maksim.khramtsov --- .changeset/real-kangaroos-push.md | 5 +++ packages/effect/src/ExecutionStrategy.ts | 12 +++++- packages/effect/src/StreamHaltStrategy.ts | 16 +++++++- .../effect/src/internal/executionStrategy.ts | 26 +++++++------ .../src/internal/stream/haltStrategy.ts | 37 ++++++++++++------- 5 files changed, 66 insertions(+), 30 deletions(-) create mode 100644 .changeset/real-kangaroos-push.md diff --git a/.changeset/real-kangaroos-push.md b/.changeset/real-kangaroos-push.md new file mode 100644 index 00000000000..b01f92b2f11 --- /dev/null +++ b/.changeset/real-kangaroos-push.md @@ -0,0 +1,5 @@ +--- +"effect": minor +--- + +The signatures of the `HaltStrategy.match` `StreamHaltStrategy.match` functions have been changed to the generally accepted ones diff --git a/packages/effect/src/ExecutionStrategy.ts b/packages/effect/src/ExecutionStrategy.ts index 94cdb14956c..5dba91eda74 100644 --- a/packages/effect/src/ExecutionStrategy.ts +++ b/packages/effect/src/ExecutionStrategy.ts @@ -106,6 +106,14 @@ export const isParallelN: (self: ExecutionStrategy) => self is ParallelN = inter * @category folding */ export const match: { - (onSequential: LazyArg, onParallel: LazyArg, onParallelN: (n: number) => A): (self: ExecutionStrategy) => A - (self: ExecutionStrategy, onSequential: LazyArg, onParallel: LazyArg, onParallelN: (n: number) => A): A + (options: { + readonly onSequential: LazyArg + readonly onParallel: LazyArg + readonly onParallelN: (n: number) => A + }): (self: ExecutionStrategy) => A + (self: ExecutionStrategy, options: { + readonly onSequential: LazyArg + readonly onParallel: LazyArg + readonly onParallelN: (n: number) => A + }): A } = internal.match diff --git a/packages/effect/src/StreamHaltStrategy.ts b/packages/effect/src/StreamHaltStrategy.ts index 1a582d3b782..5d7b055afbf 100644 --- a/packages/effect/src/StreamHaltStrategy.ts +++ b/packages/effect/src/StreamHaltStrategy.ts @@ -102,10 +102,22 @@ export const isBoth: (self: HaltStrategy) => self is Both = internal.isBoth export const isEither: (self: HaltStrategy) => self is Either = internal.isEither /** + * Folds over the specified `HaltStrategy` using the provided case functions. + * * @since 2.0.0 * @category folding */ export const match: { - (onLeft: () => Z, onRight: () => Z, onBoth: () => Z, onEither: () => Z): (self: HaltStrategy) => Z - (self: HaltStrategy, onLeft: () => Z, onRight: () => Z, onBoth: () => Z, onEither: () => Z): Z + (options: { + readonly onLeft: () => Z + readonly onRight: () => Z + readonly onBoth: () => Z + readonly onEither: () => Z + }): (self: HaltStrategy) => Z + (self: HaltStrategy, options: { + readonly onLeft: () => Z + readonly onRight: () => Z + readonly onBoth: () => Z + readonly onEither: () => Z + }): Z } = internal.match diff --git a/packages/effect/src/internal/executionStrategy.ts b/packages/effect/src/internal/executionStrategy.ts index fbd78740296..426a0d93d21 100644 --- a/packages/effect/src/internal/executionStrategy.ts +++ b/packages/effect/src/internal/executionStrategy.ts @@ -46,27 +46,29 @@ export const isParallelN = (self: ExecutionStrategy.ExecutionStrategy): self is /** @internal */ export const match = dual< - ( - onSequential: LazyArg, - onParallel: LazyArg, - onParallelN: (n: number) => A - ) => (self: ExecutionStrategy.ExecutionStrategy) => A, + (options: { + readonly onSequential: LazyArg + readonly onParallel: LazyArg + readonly onParallelN: (n: number) => A + }) => (self: ExecutionStrategy.ExecutionStrategy) => A, ( self: ExecutionStrategy.ExecutionStrategy, - onSequential: LazyArg, - onParallel: LazyArg, - onParallelN: (n: number) => A + options: { + readonly onSequential: LazyArg + readonly onParallel: LazyArg + readonly onParallelN: (n: number) => A + } ) => A ->(4, (self, onSequential, onParallel, onParallelN) => { +>(2, (self, options) => { switch (self._tag) { case OP_SEQUENTIAL: { - return onSequential() + return options.onSequential() } case OP_PARALLEL: { - return onParallel() + return options.onParallel() } case OP_PARALLEL_N: { - return onParallelN(self.parallelism) + return options.onParallelN(self.parallelism) } } }) diff --git a/packages/effect/src/internal/stream/haltStrategy.ts b/packages/effect/src/internal/stream/haltStrategy.ts index 1ffe4dad61c..0115554ef47 100644 --- a/packages/effect/src/internal/stream/haltStrategy.ts +++ b/packages/effect/src/internal/stream/haltStrategy.ts @@ -53,33 +53,42 @@ export const isEither = (self: HaltStrategy.HaltStrategy): self is HaltStrategy. /** @internal */ export const match = dual< - (onLeft: () => Z, onRight: () => Z, onBoth: () => Z, onEither: () => Z) => (self: HaltStrategy.HaltStrategy) => Z, + (options: { + readonly onLeft: () => Z + readonly onRight: () => Z + readonly onBoth: () => Z + readonly onEither: () => Z + }) => (self: HaltStrategy.HaltStrategy) => Z, ( self: HaltStrategy.HaltStrategy, - onLeft: () => Z, - onRight: () => Z, - onBoth: () => Z, - onEither: () => Z + options: { + readonly onLeft: () => Z + readonly onRight: () => Z + readonly onBoth: () => Z + readonly onEither: () => Z + } ) => Z ->(5, ( +>(2, ( self: HaltStrategy.HaltStrategy, - onLeft: () => Z, - onRight: () => Z, - onBoth: () => Z, - onEither: () => Z + options: { + readonly onLeft: () => Z + readonly onRight: () => Z + readonly onBoth: () => Z + readonly onEither: () => Z + } ): Z => { switch (self._tag) { case OpCodes.OP_LEFT: { - return onLeft() + return options.onLeft() } case OpCodes.OP_RIGHT: { - return onRight() + return options.onRight() } case OpCodes.OP_BOTH: { - return onBoth() + return options.onBoth() } case OpCodes.OP_EITHER: { - return onEither() + return options.onEither() } } })