| 944 | * @since 4.0.0 |
| 945 | */ |
| 946 | export const Schema = < |
| 947 | A extends Schema_.Constraint = Schema_.Never, |
| 948 | E extends Schema_.Constraint = Schema_.Never |
| 949 | >( |
| 950 | options: { |
| 951 | readonly success?: A | undefined |
| 952 | readonly error?: E | undefined |
| 953 | } |
| 954 | ): Schema<A, E> => { |
| 955 | const success_: A = options.success ?? Schema_.Never as any |
| 956 | const error: E = options.error ?? Schema_.Never as any |
| 957 | const schema = Schema_.declareConstructor< |
| 958 | AsyncResult<A["Type"], E["Type"]>, |
| 959 | AsyncResult<A["Encoded"], E["Encoded"]> |
| 960 | >()( |
| 961 | [success_, Schema_.Cause(error, Schema_.Defect())], |
| 962 | ([value, cause]) => (input, ast, options) => { |
| 963 | if (!isAsyncResult(input)) { |
| 964 | return Effect.fail(new SchemaIssue.InvalidType(ast, input, options)) |
| 965 | } |
| 966 | switch (input._tag) { |
| 967 | case "Initial": |
| 968 | return Effect.succeed(input) |
| 969 | case "Success": |
| 970 | return Effect.mapBothEager( |
| 971 | SchemaParser.decodeUnknownEffect(value)(input.value, options), |
| 972 | { |
| 973 | onSuccess: (value) => success(value, input), |
| 974 | onFailure: (issue) => SchemaIssue.makeCompositeAtKey(ast, "value", issue, input, options) |
| 975 | } |
| 976 | ) |
| 977 | case "Failure": { |
| 978 | const prevSuccessEffect = input.previousSuccess.pipe( |
| 979 | Option.map((ps) => |
| 980 | Effect.mapBothEager( |
| 981 | SchemaParser.decodeUnknownEffect(value)(ps.value, options), |
| 982 | { |
| 983 | onSuccess: (value) => Option.some(success<A["Type"], E["Type"]>(value, ps)), |
| 984 | onFailure: (issue) => |
| 985 | new SchemaIssue.Composite( |
| 986 | ast, |
| 987 | [ |
| 988 | new SchemaIssue.Pointer(["previousSuccess", "value"], issue) |
| 989 | ], |
| 990 | input, |
| 991 | options |
| 992 | ) |
| 993 | } |
| 994 | ) |
| 995 | ), |
| 996 | Option.getOrElse(() => Effect.succeedNone) |
| 997 | ) |
| 998 | const causeEffect = Effect.mapErrorEager( |
| 999 | SchemaParser.decodeUnknownEffect(cause)(input.cause, options), |
| 1000 | (issue) => SchemaIssue.makeCompositeAtKey(ast, "cause", issue, input, options) |
| 1001 | ) |
| 1002 | return Effect.flatMapEager( |
| 1003 | prevSuccessEffect, |