-module(outcome). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([defect/1, failure/1, stack_to_problems/1, unwrap_failure/2, into_defect/1, into_failure/1, map_into_defect/2, as_defect/2, as_failure/2, add_to_stack/2, context/2]). -export_type([error/0, error_stack/0]). -type error() :: {context, binary()} | {defect, binary()} | {failure, binary()}. -type error_stack() :: {error_stack, error(), list(error())}. -spec defect(binary()) -> {ok, any()} | {error, error_stack()}. defect(Defect) -> {error, {error_stack, {defect, Defect}, []}}. -spec failure(binary()) -> {ok, any()} | {error, error_stack()}. failure(Failure) -> {error, {error_stack, {failure, Failure}, []}}. -spec stack_to_problems(error_stack()) -> list(error()). stack_to_problems(Stack) -> [erlang:element(2, Stack) | erlang:element(3, Stack)]. -spec unwrap_failure(error_stack(), binary()) -> binary(). unwrap_failure(Stack, Default) -> _pipe = Stack, _pipe@1 = stack_to_problems(_pipe), gleam@list:fold_until( _pipe@1, Default, fun(Message, Problem) -> case Problem of {context, _} -> {continue, Message}; {defect, _} -> {stop, Message}; {failure, Failure_message} -> {stop, Failure_message} end end ). -spec into_defect({ok, FWO} | {error, binary()}) -> {ok, FWO} | {error, error_stack()}. into_defect(Result) -> gleam@result:map_error(Result, fun(E) -> {error_stack, {defect, E}, []} end). -spec into_failure({ok, FWS} | {error, binary()}) -> {ok, FWS} | {error, error_stack()}. into_failure(Result) -> gleam@result:map_error( Result, fun(E) -> {error_stack, {failure, E}, []} end ). -spec map_into_defect({ok, FWW} | {error, FWX}, fun((FWX) -> binary())) -> {ok, FWW} | {error, error_stack()}. map_into_defect(Result, Mapper) -> _pipe = Result, _pipe@1 = gleam@result:map_error(_pipe, Mapper), into_defect(_pipe@1). -spec as_defect({ok, FXB} | {error, nil}, binary()) -> {ok, FXB} | {error, error_stack()}. as_defect(Result, E) -> gleam@result:replace_error(Result, {error_stack, {defect, E}, []}). -spec as_failure({ok, FXF} | {error, nil}, binary()) -> {ok, FXF} | {error, error_stack()}. as_failure(Result, E) -> gleam@result:replace_error(Result, {error_stack, {failure, E}, []}). -spec add_to_stack(error_stack(), error()) -> error_stack(). add_to_stack(Stack, New_problem) -> {error_stack, New_problem, [erlang:element(2, Stack) | erlang:element(3, Stack)]}. -spec context({ok, FXJ} | {error, error_stack()}, binary()) -> {ok, FXJ} | {error, error_stack()}. context(Outcome, Context) -> gleam@result:map_error( Outcome, fun(Stack) -> add_to_stack(Stack, {context, Context}) end ).