Trogon.Result (Trogon.Result v1.0.1)
View SourceHandles t/0 responses. Inspired by Rust std::result::Result package.
Summary
Types
An Error result with any reason type.
An Error result with a specific reason type.
A lazy function that produces a value when called with no arguments.
A mapper function that transforms a value from type a to type b.
An Ok result with any value type.
An Ok result with a specific value type.
A predicate function that takes a value and returns a boolean.
A Result Tuple with any value types.
A Result Tuple with specific ok and error types.
A side-effect function used for tapping into values without transforming them.
Functions
Do an and with a err/0.
Do an and with a ok/0.
Returns true if the err/0 result contains the given value.
Returns true if the ok/0 result contains the given value.
Wraps a value into an err/1 result.
Returns true if the result is err/0 and the value inside of it matches a predicate.
Returns the contained ok/0 value, or raise an exception with the given error message.
Returns the contained ok/0 value, or raise an exception with the given error message.
Is valid if and only if an err/0 is supplied.
Is valid if and only if an ok/0 is supplied.
Returns true if the result is ok/0 and the value inside of it matches a predicate.
Tap into err/0 results.
Tap into ok/0 results.
Unwrap an err/0 result, or raise an exception.
Returns the contained ok/0 value or a provided default.
Unwrap an ok/0 result, or raise an exception.
Applies a function or returns the value when a ok/0 is given, or propagates the error.
Types
An Error result with any reason type.
@type err(reason) :: {:error, reason}
An Error result with a specific reason type.
@type lazy(a) :: (-> a)
A lazy function that produces a value when called with no arguments.
@type mapper(a, b) :: (a -> b)
A mapper function that transforms a value from type a to type b.
An Ok result with any value type.
@type ok(value) :: {:ok, value}
An Ok result with a specific value type.
@type predicate(a) :: (a -> boolean())
A predicate function that takes a value and returns a boolean.
A Result Tuple with any value types.
A Result Tuple with specific ok and error types.
Examples
@type fetch_user_error :: :not_found | :db_error
@spec fetch_user(integer()) :: Trogon.Result.t(User.t(), fetch_user_error())
def fetch_user(id), do: ...
@type tap_func(a) :: (a -> any())
A side-effect function used for tapping into values without transforming them.
Functions
@spec and_err(first_result :: t(a, any()), second_result :: t(a, e)) :: t(a, e) when a: any(), e: any()
Do an and with a err/0.
When passing any ok/0 result, it returns the first ok/0 value. Otherwise, when passing two err/0 results,
then returns the second err/0.
iex> 21
...> |> Trogon.Result.ok()
...> |> Trogon.Result.and_err(Trogon.Result.ok(42))
{:ok, 21}
iex> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.and_err(Trogon.Result.err("something went wrong"))
{:ok, 42}
iex> "something went wrong"
...> |> Trogon.Result.err()
...> |> Trogon.Result.and_err(Trogon.Result.ok(42))
{:ok, 42}
iex> "something went wrong"
...> |> Trogon.Result.err()
...> |> Trogon.Result.and_err(Trogon.Result.err("late error"))
{:error, "late error"}
@spec and_ok(first_result :: t(any(), e), second_result :: t(b, e)) :: t(b, e) when b: any(), e: any()
Do an and with a ok/0.
When passing two ok/0 result, it returns the second ok/0 value. When a ok/0 and a err/0 result, then
returns the err/0. Otherwise, when passing two err/0 result, it returns the earliest err/0.
iex> 21
...> |> Trogon.Result.ok()
...> |> Trogon.Result.and_ok(Trogon.Result.ok(42))
{:ok, 42}
iex> 21
...> |> Trogon.Result.ok()
...> |> Trogon.Result.and_ok(Trogon.Result.err("something went wrong"))
{:error, "something went wrong"}
iex> "something went wrong"
...> |> Trogon.Result.err()
...> |> Trogon.Result.and_ok(Trogon.Result.ok(42))
{:error, "something went wrong"}
iex> "something went wrong"
...> |> Trogon.Result.err()
...> |> Trogon.Result.and_ok(Trogon.Result.err("late error"))
{:error, "something went wrong"}
@spec collect(Enumerable.t(t(a, e))) :: t([a], e) when a: any(), e: any()
Iterate over t/0 list unwrapping the ok/0 values. It fails at the first err/0.
iex> Trogon.Result.collect([
...> Trogon.Result.ok(21),
...> Trogon.Result.ok(42),
...> Trogon.Result.ok(84),
...> ])
{:ok, [21,42,84]}
iex> Trogon.Result.collect([
...> Trogon.Result.ok(21),
...> Trogon.Result.err("oops"),
...> Trogon.Result.ok(84),
...> ])
{:error, "oops"}
Returns true if the err/0 result contains the given value.
iex> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.contains_err?("oops")
true
iex> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.contains_err?("nop")
false
iex> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.contains_err?("ops")
false
Returns true if the ok/0 result contains the given value.
iex> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.contains_ok?(42)
true
iex> 21
...> |> Trogon.Result.ok()
...> |> Trogon.Result.contains_ok?(42)
false
iex> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.contains_ok?(42)
false
Wraps a value into an err/1 result.
iex> Trogon.Result.err("oops")
{:error, "oops"}
Returns true if the argument is an err/0.
iex> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.err?()
false
iex> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.err?()
true
Returns true if the result is err/0 and the value inside of it matches a predicate.
iex> is_not_found = fn err -> err == :not_found end
...> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.err_and?(is_not_found)
false
iex> is_not_found = fn err -> err == :not_found end
...> :not_found
...> |> Trogon.Result.err()
...> |> Trogon.Result.err_and?(is_not_found)
true
Returns the contained ok/0 value, or raise an exception with the given error message.
iex> try do
...> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.expect_err!("expected a oops")
...> rescue
...> e -> e.message
...> end
"expected a oops"
iex> try do
...> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.expect_err!("expected a oops")
...> rescue
...> _ -> "was a unwrap failure"
...> end
"oops"
Returns the contained ok/0 value, or raise an exception with the given error message.
iex> try do
...> 21
...> |> Trogon.Result.err()
...> |> Trogon.Result.expect_ok!("expected 42")
...> rescue
...> e -> e.message
...> end
"expected 42"
iex> try do
...> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.expect_ok!("expected 42")
...> rescue
...> _ -> "was a unwrap failure"
...> end
42
Converts from a nested t/0 to flatten t/0.
iex> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.ok()
...> |> Trogon.Result.flatten()
{:ok, 42}
iex> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.err()
...> |> Trogon.Result.flatten()
{:error, {:ok, 42}}
iex> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.ok()
...> |> Trogon.Result.flatten()
{:error, "oops"}
iex> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.err()
...> |> Trogon.Result.flatten()
{:error, {:error, "oops"}}
Is valid if and only if an err/0 is supplied.
iex> check = fn
...> val when Trogon.Result.is_err_result(val) -> true
...> _ -> false
...> end
...> 42
...> |> Trogon.Result.ok()
...> |> check.()
false
iex> check = fn
...> val when Trogon.Result.is_err_result(val) -> true
...> _ -> false
...> end
...> "oops"
...> |> Trogon.Result.err()
...> |> check.()
true
Is valid if and only if an ok/0 is supplied.
iex> check = fn
...> val when Trogon.Result.is_ok_result(val) -> true
...> _ -> false
...> end
...> 42
...> |> Trogon.Result.ok()
...> |> check.()
true
iex> check = fn
...> val when Trogon.Result.is_ok_result(val) -> true
...> _ -> false
...> end
...> "oops"
...> |> Trogon.Result.err()
...> |> check.()
false
@spec map_err(result :: t(a, e1), on_error :: mapper(e1, e2)) :: t(a, e2) when a: any(), e1: any(), e2: any()
@spec map_err(result :: t(a, e1), on_error :: e2) :: t(a, e2) when a: any(), e1: any(), e2: any()
When the value contained in an err/0 result then applies a function or returns the mapped value, wrapping the
returning value in a err/0, propagating the ok/0 result as it is.
Avoid Wrapping
If you want to avoid the wrap then use Trogon.Result.when_err/2 instead.
iex> 21
...> |> Trogon.Result.err()
...> |> Trogon.Result.map_err("must be 42")
{:error, "must be 42"}
iex> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.map_err("must be 42")
{:ok, 42}You can also pass a function to achieve lazy evaluation:
iex> meaning_of_life = fn x -> "must be 42 instead of #{x}" end
...> 21
...> |> Trogon.Result.err()
...> |> Trogon.Result.map_err(meaning_of_life)
{:error, "must be 42 instead of 21"}
@spec map_ok(result :: t(a, e), on_ok :: mapper(a, b)) :: t(b, e) when a: any(), b: any(), e: any()
@spec map_ok(result :: t(a, e), on_ok :: b) :: t(b, e) when a: any(), b: any(), e: any()
When the value contained in an ok/0 result then applies a function or returns the mapped value, wrapping the
returning value in a ok/0, propagating the err/0 result as it is.
Avoid Wrapping
If you want to avoid the wrap then use Trogon.Result.when_ok/2 instead.
iex> 21
...> |> Trogon.Result.ok()
...> |> Trogon.Result.map_ok(42)
{:ok, 42}
iex> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.map_ok(42)
{:error, "oops"}You can also pass a function to achieve lazy evaluation:
iex> meaning_of_life = fn x -> x * 2 end
...> 21
...> |> Trogon.Result.ok()
...> |> Trogon.Result.map_ok(meaning_of_life)
{:ok, 42}
@spec map_ok_or( result :: t(a, e), on_ok :: mapper(a, b), on_error :: mapper(e, b) | b ) :: b when a: any(), b: any(), e: any()
Applies a on_ok function to the contained value if ok/0 otherwise applies a on_err function or return the
on_err value if err/0.
iex> meaning_of_life = fn x -> x * 2 end
...> 21
...> |> Trogon.Result.ok()
...> |> Trogon.Result.map_ok_or(meaning_of_life, 84)
42
iex> meaning_of_life = fn x -> x * 2 end
...> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.map_ok_or(meaning_of_life, 84)
84Lazy Evaluation
It is recommended to pass a function as the default value, which is lazily evaluated.
iex> meaning_of_life = fn x -> x * 2 end
...> went_wrong = fn reason -> "something went wrong because #{reason}" end
...> 21
...> |> Trogon.Result.ok()
...> |> Trogon.Result.map_ok_or(meaning_of_life, went_wrong)
42
iex> meaning_of_life = fn x -> x * 2 end
...> went_wrong = fn reason -> "something went wrong because #{reason}" end
...> "a sleepy bear"
...> |> Trogon.Result.err()
...> |> Trogon.Result.map_ok_or(meaning_of_life, went_wrong)
"something went wrong because a sleepy bear"
Wraps a value into an ok/1 result.
iex> Trogon.Result.ok(42)
{:ok, 42}
Returns true if the argument is a ok/0.
iex> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.ok?()
true
iex> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.ok?()
false
Returns true if the result is ok/0 and the value inside of it matches a predicate.
iex> is_meaning_of_life = fn x -> x == 42 end
...> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.ok_and?(is_meaning_of_life)
true
iex> is_meaning_of_life = fn x -> x == 42 end
...> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.ok_and?(is_meaning_of_life)
false
@spec reject_nil(value :: a | nil | t(a, e), on_nil :: e | lazy(e)) :: t(a, e) when a: any(), e: any()
When nil is passed then calls the on_nil function and wrap the result into a err/0. When t/0 is passed
then returns it as it is. Otherwise, wraps the value into a ok/0.
iex> Trogon.Result.reject_nil(nil, "ooopps")
{:error, "ooopps"}
iex> Trogon.Result.reject_nil(42, "ooopps")
{:ok, 42}
iex> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.reject_nil("ooopps")
{:ok, 42}
iex> "my error"
...> |> Trogon.Result.err()
...> |> Trogon.Result.reject_nil("ooopps")
{:error, "my error"}Lazy Evaluation
It is recommended to pass a function as the default value, which is lazily evaluated.
iex> new_error = fn -> "ooops" end
...> Trogon.Result.reject_nil(nil, new_error)
{:error, "ooops"}
Tap into err/0 results.
iex> failure_log = fn err -> "Failure because #{err}" end
...> "ooopsy"
...> |> Trogon.Result.err()
...> |> Trogon.Result.tap_err(failure_log)
{:error, "ooopsy"}
Tap into ok/0 results.
iex> success_log = fn x -> "Success #{x}" end
...> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.tap_ok(success_log)
{:ok, 42}
Returns the contained ok/0 value or t:error/0 value from a t/0.
iex> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.unwrap()
42
iex> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.unwrap()
"oops"
Unwrap an err/0 result, or raise an exception.
iex> try do
...> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.unwrap_err!()
...> rescue
...> Trogon.Result.ErrUnwrapError -> "was a unwrap failure"
...> end
"oops"
iex> try do
...> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.unwrap_err!()
...> rescue
...> Trogon.Result.ErrUnwrapError -> "was a unwrap failure"
...> end
"was a unwrap failure"
@spec unwrap_ok(result :: t(a, e), on_error :: mapper(e, a)) :: a when a: any(), e: any()
@spec unwrap_ok(result :: t(a, e), on_error :: a) :: a when a: any(), e: any()
Returns the contained ok/0 value or a provided default.
iex> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.unwrap_ok(21)
42
iex> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.unwrap_ok(21)
21Lazy Evaluation
It is recommended to pass a function as the default value, which is lazily evaluated.
iex> say_hello_world = fn _x -> "hello, world!" end
...> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.unwrap_ok(say_hello_world)
42
iex> say_hello_world = fn _x -> "hello, world!" end
...> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.unwrap_ok(say_hello_world)
"hello, world!"
Unwrap an ok/0 result, or raise an exception.
iex> try do
...> 42
...> |> Trogon.Result.ok()
...> |> Trogon.Result.unwrap_ok!()
...> rescue
...> Trogon.Result.OkUnwrapError -> "was a unwrap failure"
...> end
42
iex> try do
...> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.unwrap_ok!()
...> rescue
...> Trogon.Result.OkUnwrapError -> "was a unwrap failure"
...> end
"was a unwrap failure"
@spec when_err(result :: t(a, e), on_err :: mapper(e, b)) :: ok(a) | b when a: any(), b: any(), e: any()
@spec when_err(result :: t(a, e), on_err :: b) :: ok(a) | b when a: any(), b: any(), e: any()
Applies a function or returns the value if the result is err/0, otherwise returns the ok/0 value.
iex> "something wrong happened"
...> |> Trogon.Result.err()
...> |> Trogon.Result.when_err("ooops")
"ooops"
iex> 2
...> |> Trogon.Result.ok()
...> |> Trogon.Result.when_err("ooops")
{:ok, 2}You can also pass a function to achieve lazy evaluation:
iex> failure = fn _error -> "lazy ooops" end
...> "something wrong happened"
...> |> Trogon.Result.err()
...> |> Trogon.Result.when_err(failure)
"lazy ooops"
@spec when_ok(result :: t(a, e), on_ok :: mapper(a, b)) :: err(e) | b when a: any(), b: any(), e: any()
@spec when_ok(result :: t(a, e), on_ok :: b) :: err(e) | b when a: any(), b: any(), e: any()
Applies a function or returns the value when a ok/0 is given, or propagates the error.
iex> 21
...> |> Trogon.Result.ok()
...> |> Trogon.Result.when_ok(42)
42
iex> "oops"
...> |> Trogon.Result.err()
...> |> Trogon.Result.when_ok(42)
{:error, "oops"}You can also pass a function to achieve lazy evaluation:
iex> meaning_of_life = fn x -> x * 2 end
...> 21
...> |> Trogon.Result.ok()
...> |> Trogon.Result.when_ok(meaning_of_life)
42