-module(outcome). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([error_with_defect/1, error_with_failure/1, into_defect/1, into_failure/1, map_into_defect/2, map_into_failure/2, replace_with_defect/2, replace_with_failure/2, map_error/2, to_defect/1, to_failure/1, with_context/2, unwrap_failure/2, extract_error/1, pretty_print/2, print_line/2]). -export_type([problem/1]). -type problem(FWG) :: {defect, FWG, list(binary())} | {failure, FWG, list(binary())}. -spec new_defect(FWN) -> problem(FWN). new_defect(Value) -> {defect, Value, []}. -spec new_failure(FWP) -> problem(FWP). new_failure(Value) -> {failure, Value, []}. -spec error_with_defect(FWR) -> {ok, any()} | {error, problem(FWR)}. error_with_defect(Defect) -> {error, new_defect(Defect)}. -spec error_with_failure(FWV) -> {ok, any()} | {error, problem(FWV)}. error_with_failure(Failure) -> {error, new_failure(Failure)}. -spec into_defect({ok, FWZ} | {error, FXA}) -> {ok, FWZ} | {error, problem(FXA)}. into_defect(Result) -> gleam@result:map_error(Result, fun new_defect/1). -spec into_failure({ok, FXF} | {error, FXG}) -> {ok, FXF} | {error, problem(FXG)}. into_failure(Result) -> gleam@result:map_error(Result, fun new_failure/1). -spec map_into_defect({ok, FXL} | {error, FXM}, fun((FXM) -> FXP)) -> {ok, FXL} | {error, problem(FXP)}. map_into_defect(Result, Mapper) -> _pipe = Result, _pipe@1 = gleam@result:map_error(_pipe, Mapper), into_defect(_pipe@1). -spec map_into_failure({ok, FXS} | {error, FXT}, fun((FXT) -> FXW)) -> {ok, FXS} | {error, problem(FXW)}. map_into_failure(Result, Mapper) -> _pipe = Result, _pipe@1 = gleam@result:map_error(_pipe, Mapper), into_failure(_pipe@1). -spec replace_with_defect({ok, FXZ} | {error, nil}, FYC) -> {ok, FXZ} | {error, problem(FYC)}. replace_with_defect(Result, E) -> gleam@result:replace_error(Result, new_defect(E)). -spec replace_with_failure({ok, FYF} | {error, nil}, FYI) -> {ok, FYF} | {error, problem(FYI)}. replace_with_failure(Result, E) -> gleam@result:replace_error(Result, new_failure(E)). -spec map_error_in_problem(problem(FYL), fun((FYL) -> FYL)) -> problem(FYL). map_error_in_problem(Problem, Mapper) -> case Problem of {defect, Error, Stack} -> {defect, Mapper(Error), Stack}; {failure, Error@1, Stack@1} -> {failure, Mapper(Error@1), Stack@1} end. -spec map_error({ok, FYO} | {error, problem(FYP)}, fun((FYP) -> FYP)) -> {ok, FYO} | {error, problem(FYP)}. map_error(Outcome, Mapper) -> gleam@result:map_error( Outcome, fun(_capture) -> map_error_in_problem(_capture, Mapper) end ). -spec problem_to_defect(problem(FZG)) -> problem(FZG). problem_to_defect(Problem) -> {defect, erlang:element(2, Problem), erlang:element(3, Problem)}. -spec to_defect({ok, FZA} | {error, problem(FZB)}) -> {ok, FZA} | {error, problem(FZB)}. to_defect(Outcome) -> gleam@result:map_error(Outcome, fun problem_to_defect/1). -spec problem_to_failure(problem(FZP)) -> problem(FZP). problem_to_failure(Problem) -> {failure, erlang:element(2, Problem), erlang:element(3, Problem)}. -spec to_failure({ok, FZJ} | {error, problem(FZK)}) -> {ok, FZJ} | {error, problem(FZK)}. to_failure(Outcome) -> gleam@result:map_error(Outcome, fun problem_to_failure/1). -spec push_to_stack(list(binary()), binary()) -> list(binary()). push_to_stack(Stack, Entry) -> [Entry | Stack]. -spec add_context_to_problem(problem(FZT), binary()) -> problem(FZT). add_context_to_problem(Problem, Value) -> case Problem of {defect, Error, Stack} -> {defect, Error, push_to_stack(Stack, Value)}; {failure, Error@1, Stack@1} -> {failure, Error@1, push_to_stack(Stack@1, Value)} end. -spec with_context({ok, FYU} | {error, problem(FYV)}, binary()) -> {ok, FYU} | {error, problem(FYV)}. with_context(Outcome, Context) -> gleam@result:map_error( Outcome, fun(_capture) -> add_context_to_problem(_capture, Context) end ). -spec unwrap_failure(problem(FZW), FZW) -> FZW. unwrap_failure(Problem, Default_value) -> case Problem of {defect, _, _} -> Default_value; {failure, Value, _} -> Value end. -spec problem_to_error(problem(GAE)) -> GAE. problem_to_error(Problem) -> erlang:element(2, Problem). -spec extract_error({ok, FZY} | {error, problem(FZZ)}) -> {ok, FZY} | {error, FZZ}. extract_error(Outcome) -> _pipe = Outcome, gleam@result:map_error(_pipe, fun problem_to_error/1). -spec long_suffix(problem(any())) -> binary(). long_suffix(Problem) -> case Problem of {defect, _, _} -> <<"Defect: "/utf8>>; {failure, _, _} -> <<"Failure: "/utf8>> end. -spec prettry_print_error(binary(), GAR, fun((GAR) -> binary())) -> binary(). prettry_print_error(Suffix, Error, To_s) -> <>. -spec prettry_print_problem_error(problem(GAN), fun((GAN) -> binary())) -> binary(). prettry_print_problem_error(Problem, To_s) -> prettry_print_error(long_suffix(Problem), erlang:element(2, Problem), To_s). -spec pretty_print_stack_entry(binary()) -> binary(). pretty_print_stack_entry(Value) -> Value. -spec stack_to_lines(list(binary())) -> list(binary()). stack_to_lines(Stack) -> _pipe = Stack, gleam@list:map(_pipe, fun pretty_print_stack_entry/1). -spec pretty_print_with_joins( problem(GAL), binary(), binary(), fun((GAL) -> binary()) ) -> binary(). pretty_print_with_joins(Problem, Join_current, Join_stack, To_s) -> Current = prettry_print_problem_error(Problem, To_s), Stack = begin _pipe = erlang:element(3, Problem), _pipe@1 = stack_to_lines(_pipe), gleam@string:join(_pipe@1, Join_stack) end, <<<>/binary, Stack/binary>>. -spec pretty_print(problem(GAH), fun((GAH) -> binary())) -> binary(). pretty_print(Problem, To_s) -> pretty_print_with_joins( Problem, <<"\n\nstack:\n "/utf8>>, <<"\n "/utf8>>, To_s ). -spec print_line(problem(GAJ), fun((GAJ) -> binary())) -> binary(). print_line(Problem, To_s) -> pretty_print_with_joins(Problem, <<" << "/utf8>>, <<" < "/utf8>>, To_s).