-module(outcome). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -define(FILEPATH, "src/outcome.gleam"). -export([context/2, with_context/2, new_problem/1, outcome/1, map_error/2, remove_problem/1, pretty_print/2, print_line/2]). -export_type([problem/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -type problem(FVF) :: {problem, FVF, list(binary())}. -file("src/outcome.gleam", 18). -spec push_to_stack(list(binary()), binary()) -> list(binary()). push_to_stack(Stack, Entry) -> [Entry | Stack]. -file("src/outcome.gleam", 60). -spec problem_context(problem(FVV), binary()) -> problem(FVV). problem_context(Problem, Value) -> _record = Problem, {problem, erlang:element(2, _record), push_to_stack(erlang:element(3, Problem), Value)}. -file("src/outcome.gleam", 33). ?DOC( " Add context to a Problem.\n" " This will add a context entry to the stack.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " Error(\"Something went wrong\")\n" " |> outcome.outcome\n" " |> outcome.context(\"In find user function\")\n" " ```\n" ). -spec context({ok, FVN} | {error, problem(FVO)}, binary()) -> {ok, FVN} | {error, problem(FVO)}. context(Outcome, Context) -> gleam@result:map_error( Outcome, fun(_capture) -> problem_context(_capture, Context) end ). -file("src/outcome.gleam", 55). ?DOC( " Convenient function for adding context\n" " at the top of a function that returns an Outcome.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " fn do_something(user_id: String) -> Outcome(AnswerType, ErrorType) {\n" " use <- with_context(\"user_id \" <> user_id)\n" "\n" " ...\n" " }\n" "\n" " This is equivalent to adding `|> outcome.context(...)` to each\n" " of the results in the body of the function\n" ). -spec with_context(binary(), fun(() -> {ok, FXN} | {error, problem(FXO)})) -> {ok, FXN} | {error, problem(FXO)}. with_context(Error_context, Next) -> _pipe = Next(), context(_pipe, Error_context). -file("src/outcome.gleam", 86). ?DOC( " Create a `Problem`\n" " Use this if you need the `Problem` type only.\n" " Usually you will use `outcome` instead.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " outcome.new_problem(\"Something went wrong\")\n" " ```\n" ). -spec new_problem(FWE) -> problem(FWE). new_problem(Error) -> {problem, Error, []}. -file("src/outcome.gleam", 72). ?DOC( " Convert `Result(a, e)` to `Result(a, Problem(e))`\n" "\n" " ## Example\n" "\n" " ```gleam\n" " Error(\"Something went wrong\")\n" " |> outcome.outcome\n" " ```\n" ). -spec outcome({ok, FVY} | {error, FVZ}) -> {ok, FVY} | {error, problem(FVZ)}. outcome(Result) -> gleam@result:map_error(Result, fun new_problem/1). -file("src/outcome.gleam", 98). -spec problem_map_error(problem(FWM), fun((FWM) -> FWM)) -> problem(FWM). problem_map_error(Problem, Mapper) -> _record = Problem, {problem, Mapper(erlang:element(2, Problem)), erlang:element(3, _record)}. -file("src/outcome.gleam", 91). ?DOC(" Map the error value\n"). -spec map_error({ok, FWG} | {error, problem(FWH)}, fun((FWH) -> FWH)) -> {ok, FWG} | {error, problem(FWH)}. map_error(Outcome, Mapper) -> gleam@result:map_error( Outcome, fun(_capture) -> problem_map_error(_capture, Mapper) end ). -file("src/outcome.gleam", 114). ?DOC( " Remove the `Problem` wrapping in the error value\n" "\n" " ## Example\n" "\n" " ```gleam\n" " let outcome = Error(\"Fail\") |> outcome.outcome\n" "\n" " outcome.remove_problem(outcome) == Error(\"Fail\")\n" " ```\n" ). -spec remove_problem({ok, FWP} | {error, problem(FWQ)}) -> {ok, FWP} | {error, FWQ}. remove_problem(Outcome) -> _pipe = Outcome, gleam@result:map_error( _pipe, fun(Problem) -> erlang:element(2, Problem) end ). -file("src/outcome.gleam", 198). -spec stack_to_lines(list(binary())) -> list(binary()). stack_to_lines(Stack) -> _pipe = Stack, lists:reverse(_pipe). -file("src/outcome.gleam", 176). -spec pretty_print_with_joins( problem(FWZ), binary(), binary(), fun((FWZ) -> binary()) ) -> binary(). pretty_print_with_joins(Problem, Join_current, Join_stack, To_s) -> Current = To_s(erlang:element(2, Problem)), Stack = <>, Stack@1 = case erlang:element(3, Problem) of [] -> <<""/utf8>>; _ -> Stack end, <>. -file("src/outcome.gleam", 148). ?DOC( " Pretty print a Problem, including the stack.\n" " The latest problem appears at the top of the stack.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " let result = Error(\"Something went wrong\")\n" " |> outcome.outcome\n" " |> outcome.context(\"In find user function\")\n" " |> outcome.context(\"More context\")\n" "\n" " case result {\n" " Error(problem) ->\n" " outcome.pretty_print(function.identity)\n" "\n" " Ok(_) -> todo\n" " }\n" " ```\n" "\n" " ```\n" " Something went wrong\n" "\n" " stack:\n" " In find user function\n" " More context\n" " ```\n" ). -spec pretty_print(problem(FWV), fun((FWV) -> binary())) -> binary(). pretty_print(Problem, To_s) -> pretty_print_with_joins( Problem, <<"\n\nstack:\n "/utf8>>, <<"\n "/utf8>>, To_s ). -file("src/outcome.gleam", 172). ?DOC( " Print problem in one line\n" "\n" " ## Example\n" "\n" " ```gleam\n" " let result = Error(\"Something went wrong\")\n" " |> outcome.outcome\n" " |> outcome.context(\"In find user function\")\n" "\n" " case result {\n" " Error(problem) ->\n" " outcome.print_line(function.identity)\n" "\n" " Ok(_) -> todo\n" " }\n" " ```\n" "\n" " ```\n" " Something went wrong < In find user function\n" " ```\n" ). -spec print_line(problem(FWX), fun((FWX) -> binary())) -> binary(). print_line(Problem, To_s) -> pretty_print_with_joins(Problem, <<" < "/utf8>>, <<" < "/utf8>>, To_s).