View Source OnePiece.Result (OnePiece.Result v0.1.0)

Handles t/0 responses. Inspired by Rust std::result::Result package.

Link to this section Summary

Types

An Error result.

An Ok result.

t()

An Result Tuple.

Functions

Iterate over t/0 list unwrapping the ok/0 values. It fails at the first err/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/0 result.

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.

Converts from a nested t/0 to flatten t/0.

Returns true if the result is err/0 and the value inside of it matches a predicate.

Is valid if and only if an err/0 is supplied.

Returns true if the argument is an err/0.

Returns true if the result is ok/0 and the value inside of it matches a predicate.

Is valid if and only if an ok/0 is supplied.

Returns true if the argument is a ok/0.

Apply a function to the value contained in an err/0 result wrapping the returning in a err/0. It propagates the ok/0 result.

Apply a function to the value contained in an ok/0 wrapping the returned value in a ok/0. It propagates the err/0 result.

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.

Wraps a value into an ok/0 result.

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.

Tap into err/0 results.

Tap into ok/0 results.

Unwrap an err/0 result, or raise an exception.

Unwrap an ok/0 result, or raise an exception.

Returns the contained ok/0 value or a provided default.

Calls the closure if the result is err/0, otherwise returns the ok/0 value.

Applies a function when a ok/0 is given, or propagates the error.

Link to this section Types

@type err() :: {:error, any()}

An Error result.

@type ok() :: {:ok, any()}

An Ok result.

@type t() :: ok() | err()

An Result Tuple.

Link to this section Functions

Link to this function

and_err(first_result, second_result)

View Source
@spec and_err(first_result :: t(), second_result :: t()) :: t()

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
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.and_err(OnePiece.Result.ok(42))
{:ok, 21}

iex> 42
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.and_err(OnePiece.Result.err("something went wrong"))
{:ok, 42}

iex> "something went wrong"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.and_err(OnePiece.Result.ok(42))
{:ok, 42}

iex> "something went wrong"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.and_err(OnePiece.Result.err("late error"))
{:error, "late error"}
Link to this function

and_ok(first_result, second_result)

View Source
@spec and_ok(first_result :: t(), second_result :: t()) :: t()

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
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.and_ok(OnePiece.Result.ok(42))
{:ok, 42}

iex> 21
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.and_ok(OnePiece.Result.err("something went wrong"))
{:error, "something went wrong"}

iex> "something went wrong"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.and_ok(OnePiece.Result.ok(42))
{:error, "something went wrong"}

iex> "something went wrong"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.and_ok(OnePiece.Result.err("late error"))
{:error, "something went wrong"}
@spec collect(Enum.t()) :: t()

Iterate over t/0 list unwrapping the ok/0 values. It fails at the first err/0.

iex> OnePiece.Result.collect([
...>   OnePiece.Result.ok(21),
...>   OnePiece.Result.ok(42),
...>   OnePiece.Result.ok(84),
...> ])
{:ok, [21,42,84]}

iex> OnePiece.Result.collect([
...>   OnePiece.Result.ok(21),
...>   OnePiece.Result.err("oops"),
...>   OnePiece.Result.ok(84),
...> ])
{:error, "oops"}
Link to this function

contains_err?(arg, value)

View Source
@spec contains_err?(result :: t(), value :: any()) :: boolean()

Returns true if the err/0 result contains the given value.

iex> "oops"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.contains_err?("oops")
true

iex> "oops"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.contains_err?("nop")
false

iex> 42
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.contains_err?("ops")
false
Link to this function

contains_ok?(arg, value)

View Source
@spec contains_ok?(result :: t(), value :: any()) :: boolean()

Returns true if the ok/0 result contains the given value.

iex> 42
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.contains_ok?(42)
true

iex> 21
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.contains_ok?(42)
false

iex> "oops"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.contains_ok?(42)
false
@spec err(reason :: any()) :: err()

Wraps a value into an err/0 result.

iex> OnePiece.Result.err("oops")
{:error, "oops"}
Link to this function

expect_err!(arg, message)

View Source
@spec expect_err!(result :: t(), message :: String.t()) :: any() | no_return()

Returns the contained ok/0 value, or raise an exception with the given error message.

iex> try do
...>   42
...>   |> OnePiece.Result.ok()
...>   |> OnePiece.Result.expect_err!("expected a oops")
...> rescue
...>   e -> e.message
...> end
"expected a oops"

iex> try do
...>   "oops"
...>   |> OnePiece.Result.err()
...>   |> OnePiece.Result.expect_err!("expected a oops")
...> rescue
...>   _ -> "was a unwrap failure"
...> end
"oops"
Link to this function

expect_ok!(arg, message)

View Source
@spec expect_ok!(result :: t(), message :: String.t()) :: any() | no_return()

Returns the contained ok/0 value, or raise an exception with the given error message.

iex> try do
...>   21
...>   |> OnePiece.Result.err()
...>   |> OnePiece.Result.expect_ok!("expected 42")
...> rescue
...>   e -> e.message
...> end
"expected 42"

iex> try do
...>   42
...>   |> OnePiece.Result.ok()
...>   |> OnePiece.Result.expect_ok!("expected 42")
...> rescue
...>   _ -> "was a unwrap failure"
...> end
42
@spec flatten(result :: t()) :: t()

Converts from a nested t/0 to flatten t/0.

iex> 42
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.flatten()
{:ok, 42}

iex> 42
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.flatten()
{:error, {:ok, 42}}

iex> "oops"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.flatten()
{:error, "oops"}

iex> "oops"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.flatten()
{:error, {:error, "oops"}}
@spec is_err_and?(value :: t(), predicate :: (any() -> boolean())) :: boolean()

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
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.is_err_and?(is_not_found)
false

iex> is_not_found = fn err -> err == :not_found end
...> :not_found
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.is_err_and?(is_not_found)
true
Link to this macro

is_err_result(val)

View Source (macro)
@spec is_err_result(value :: any()) :: Macro.t()

Is valid if and only if an err/0 is supplied.

iex> check = fn
...>   val when OnePiece.Result.is_err_result(val) -> true
...>   _ -> false
...> end
...> 42
...> |> OnePiece.Result.ok()
...> |> check.()
false

iex> check = fn
...>   val when OnePiece.Result.is_err_result(val) -> true
...>   _ -> false
...> end
...> "oops"
...> |> OnePiece.Result.err()
...> |> check.()
true
@spec is_err?(value :: t()) :: boolean()

Returns true if the argument is an err/0.

iex> 42
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.is_err?()
false

iex> "oops"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.is_err?()
true
@spec is_ok_and?(value :: t(), predicate :: (any() -> boolean())) :: boolean()

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
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.is_ok_and?(is_meaning_of_life)
true

iex> is_meaning_of_life = fn x -> x == 42 end
...> "oops"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.is_ok_and?(is_meaning_of_life)
false
Link to this macro

is_ok_result(val)

View Source (macro)
@spec is_ok_result(value :: any()) :: Macro.t()

Is valid if and only if an ok/0 is supplied.

iex> check = fn
...>   val when OnePiece.Result.is_ok_result(val) -> true
...>   _ -> false
...> end
...> 42
...> |> OnePiece.Result.ok()
...> |> check.()
true

iex> check = fn
...>   val when OnePiece.Result.is_ok_result(val) -> true
...>   _ -> false
...> end
...> "oops"
...> |> OnePiece.Result.err()
...> |> check.()
false
@spec is_ok?(value :: t()) :: boolean()

Returns true if the argument is a ok/0.

iex> 42
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.is_ok?()
true

iex> "oops"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.is_ok?()
false
Link to this function

map_err(result, on_error)

View Source
@spec map_err(result :: t(), on_error :: (any() -> any())) :: t()

Apply a function to the value contained in an err/0 result wrapping the returning in a err/0. It propagates the ok/0 result.

Avoid Wrapping

If you want to avoid the wrap then use OnePiece.Result.when_err/2 instead.

iex> meaning_of_life = fn x -> "must be 42 instead of #{x}" end
...> 21
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.map_err(meaning_of_life)
{:error, "must be 42 instead of 21"}

iex> meaning_of_life = fn x -> "must be 42 instead of #{x}" end
...> 42
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.map_err(meaning_of_life)
{:ok, 42}
@spec map_ok(result :: t(), on_ok :: (any() -> any())) :: t()

Apply a function to the value contained in an ok/0 wrapping the returned value in a ok/0. It propagates the err/0 result.

Avoid Wrapping

If you want to avoid the wrap then use OnePiece.Result.when_ok/2 instead.

iex> meaning_of_life = fn x -> x * 2 end
...> 21
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.map_ok(meaning_of_life)
{:ok, 42}

iex> meaning_of_life = fn x -> x * 2 end
...> "oops"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.map_ok(meaning_of_life)
{:error, "oops"}
Link to this function

map_ok_or(arg, on_ok, on_error)

View Source
@spec map_ok_or(
  result :: t(),
  on_ok :: (any() -> any()),
  on_error :: any() | (any() -> any())
) :: 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
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.map_ok_or(meaning_of_life, 84)
42

iex> meaning_of_life = fn x -> x * 2 end
...> "oops"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.map_ok_or(meaning_of_life, 84)
84

Lazy 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
...> |> OnePiece.Result.ok()
...> |> OnePiece.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"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.map_ok_or(meaning_of_life, went_wrong)
"something went wrong because a sleepy bear"
@spec ok(value :: any()) :: ok()

Wraps a value into an ok/0 result.

iex> OnePiece.Result.ok(42)
{:ok, 42}
Link to this function

reject_nil(response, on_nil)

View Source
@spec reject_nil(value :: any(), on_nil :: (() -> any())) :: t()

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> OnePiece.Result.reject_nil(nil, "ooopps")
{:error, "ooopps"}

iex> OnePiece.Result.reject_nil(42, "ooopps")
{:ok, 42}

iex> 42
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.reject_nil("ooopps")
{:ok, 42}

iex> "my error"
...> |> OnePiece.Result.err()
...> |> OnePiece.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
...> OnePiece.Result.reject_nil(nil, new_error)
{:error, "ooops"}
@spec tap_err(result :: t(), func :: (any() -> any())) :: t()

Tap into err/0 results.

iex> failure_log = fn err -> "Failure because #{err}" end
...> "ooopsy"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.tap_err(failure_log)
{:error, "ooopsy"}
@spec tap_ok(result :: t(), func :: (any() -> any())) :: t()

Tap into ok/0 results.

iex> success_log = fn x -> "Success #{x}" end
...> 42
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.tap_ok(success_log)
{:ok, 42}
@spec unwrap_err!(result :: t()) :: any() | no_return()

Unwrap an err/0 result, or raise an exception.

iex> try do
...>   "oops"
...>   |> OnePiece.Result.err()
...>   |> OnePiece.Result.unwrap_err!()
...> rescue
...>   OnePiece.Result.ErrUnwrapError -> "was a unwrap failure"
...> end
"oops"

iex> try do
...>   42
...>   |> OnePiece.Result.ok()
...>   |> OnePiece.Result.unwrap_err!()
...> rescue
...>   OnePiece.Result.ErrUnwrapError -> "was a unwrap failure"
...> end
"was a unwrap failure"
@spec unwrap_ok!(result :: t()) :: any() | no_return()

Unwrap an ok/0 result, or raise an exception.

iex> try do
...>   42
...>   |> OnePiece.Result.ok()
...>   |> OnePiece.Result.unwrap_ok!()
...> rescue
...>   OnePiece.Result.OkUnwrapError -> "was a unwrap failure"
...> end
42

iex> try do
...>   "oops"
...>   |> OnePiece.Result.err()
...>   |> OnePiece.Result.unwrap_ok!()
...> rescue
...>   OnePiece.Result.OkUnwrapError -> "was a unwrap failure"
...> end
"was a unwrap failure"
Link to this function

unwrap_ok(arg, on_error)

View Source
@spec unwrap_ok(result :: t(), on_error :: any() | (any() -> any())) :: any()

Returns the contained ok/0 value or a provided default.

iex> 42
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.unwrap_ok(21)
42

iex> "oops"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.unwrap_ok(21)
21

Lazy 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
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.unwrap_ok(say_hello_world)
42

iex> say_hello_world = fn _x -> "hello, world!" end
...> "oops"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.unwrap_ok(say_hello_world)
"hello, world!"
@spec when_err(result :: t(), on_err :: (any() -> t())) :: t()

Calls the closure if the result is err/0, otherwise returns the ok/0 value.

iex> square = fn x -> OnePiece.Result.ok(x * x) end
...> 2
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.when_err(square)
...> |> OnePiece.Result.when_err(square)
{:ok, 2}

iex> square = fn x -> OnePiece.Result.ok(x * x) end
...> failure = fn x -> OnePiece.Result.err(x) end
...> 2
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.when_err(failure)
...> |> OnePiece.Result.when_err(square)
{:ok, 2}

iex> square = fn x -> OnePiece.Result.ok(x * x) end
...> failure = fn x -> OnePiece.Result.err(x) end
...> 3
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.when_err(square)
...> |> OnePiece.Result.when_err(failure)
{:ok, 9}

iex> failure = fn x -> OnePiece.Result.err(x) end
...> 3
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.when_err(failure)
...> |> OnePiece.Result.when_err(failure)
{:error, 3}
@spec when_ok(result :: t(), on_ok :: (any() -> any())) :: t()

Applies a function when a ok/0 is given, or propagates the error.

iex> meaning_of_life = fn x -> x * 2 end
...> 21
...> |> OnePiece.Result.ok()
...> |> OnePiece.Result.when_ok(meaning_of_life)
42

iex> meaning_of_life = fn x -> x * 2 end
...> "oops"
...> |> OnePiece.Result.err()
...> |> OnePiece.Result.when_ok(meaning_of_life)
{:error, "oops"}