Hyperlinkv0.8.0-beta.28

Schema

Source effect/Schema.ts:8813110 lines
export interface Result<A extends Constraint, E extends Constraint> extends
  declareConstructor<
    Result_.Result<A["Type"], E["Type"]>,
    Result_.Result<A["Encoded"], E["Encoded"]>,
    readonly [A, E],
    ResultIso<A, E>
  >
{
  readonly "Rebuild": Result<A, E>
  readonly success: A
  readonly failure: E
}

/**
 * Iso representation used for `Result` schemas.
 *
 * **Details**
 *
 * Successful results are represented as `{ _tag: "Success", success }`, while
 * failed results are represented as `{ _tag: "Failure", failure }`.
 *
 * @category schemas
 * @since 4.0.0
 */
export type ResultIso<A extends Constraint, E extends Constraint> =
  | { readonly _tag: "Success"; readonly success: A["Iso"] }
  | { readonly _tag: "Failure"; readonly failure: E["Iso"] }

/**
 * Schema for `Result<A, E>` values.
 *
 * @category schemas
 * @since 4.0.0
 */
export function Result<A extends Constraint, E extends Constraint>(
  success: A,
  failure: E
): Result<A, E> {
  const schema = declareConstructor<
    Result_.Result<A["Type"], E["Type"]>,
    Result_.Result<A["Encoded"], E["Encoded"]>,
    ResultIso<A, E>
  >()(
    [success, failure],
    ([success, failure]) => (input, ast, options) => {
      if (!Result_.isResult(input)) {
        return Effect.fail(new SchemaIssue.InvalidType(ast, Option_.some(input)))
      }
      switch (input._tag) {
        case "Success":
          return Effect.mapBothEager(SchemaParser.decodeEffect(success)(input.success, options), {
            onSuccess: Result_.succeed,
            onFailure: (issue) =>
              new SchemaIssue.Composite(ast, Option_.some(input), [new SchemaIssue.Pointer(["success"], issue)])
          })
        case "Failure":
          return Effect.mapBothEager(SchemaParser.decodeEffect(failure)(input.failure, options), {
            onSuccess: Result_.fail,
            onFailure: (issue) =>
              new SchemaIssue.Composite(ast, Option_.some(input), [new SchemaIssue.Pointer(["failure"], issue)])
          })
      }
    },
    {
      typeConstructor: {
        _tag: "effect/Result"
      },
      generation: {
        runtime: `Schema.Result(?, ?)`,
        Type: `Result.Result<?, ?>`,
        importDeclaration: `import * as Result from "effect/Result"`
      },
      expected: "Result",
      toCodec: ([success, failure]) =>
        link<Result_.Result<A["Encoded"], E["Encoded"]>>()(
          Union([
            Struct({ _tag: Literal("Success"), success }),
            Struct({ _tag: Literal("Failure"), failure })
          ]),
          SchemaTransformation.transform({
            decode: (e): Result_.Result<A["Encoded"], E["Encoded"]> =>
              e._tag === "Success" ? Result_.succeed(e.success) : Result_.fail(e.failure),
            encode: (r) =>
              Result_.isSuccess(r)
                ? { _tag: "Success", success: r.success } as const
                : { _tag: "Failure", failure: r.failure } as const
          })
        ),
      toArbitrary: ([success, failure]) => (fc, ctx) => {
        const terminal = oneOfArbitraries(
          fc,
          success.terminal?.map((a): Result_.Result<A["Type"], E["Type"]> => Result_.succeed(a)),
          failure.terminal?.map((e): Result_.Result<A["Type"], E["Type"]> => Result_.fail(e))
        )
        const arbitrary = fc.oneof(
          success.arbitrary.map((a): Result_.Result<A["Type"], E["Type"]> => Result_.succeed(a)),
          failure.arbitrary.map((e): Result_.Result<A["Type"], E["Type"]> => Result_.fail(e))
        )
        return withRecursion(fc, ctx, terminal, arbitrary)
      },
      toEquivalence: ([success, failure]) => Result_.makeEquivalence(success, failure),
      toFormatter: ([success, failure]) =>
        Result_.match({
          onSuccess: (t) => `success(${success(t)})`,
          onFailure: (t) => `failure(${failure(t)})`
        })
    }
  )
  return make(schema.ast, { success, failure })
}
Referenced by 1 symbols