View Source Oxide.Result (oxide v0.4.0)
Helpers for working with result tuples, {:ok, value}
and {:error, reason}
.
Unless otherwise stated, functions raise FunctionClauseError
when given an unexpected
non-result.
Summary
Functions
Result pipe operator.
Collects a list of results into a single result.
Convert a maybe-nil value to a result.
Wrap a value in an error result.
Return whether a result is an error.
Return whether a result is ok.
Return a result leaving errors unchanged but transforming the value of an :ok
result.
Return a result leaving ok values unchanged but transforming an error reason with f
.
Return an unwrapped ok value transformed by f, or default
if result
is an error.
Wrap a value in an ok result.
Return an ok result unchanged, or transform an unwrapped error reason with f
.
Equivalent to Kernel.tap/2
for error results.
Equivalent to Kernel.tap/2
for ok results.
Unwrap an :ok
result, and raise an :error
reason.
Unwrap an :ok
result, falling back to default
for an :error
result.
Unwrap an :ok
result, falling back to executing a zero-arity function if the result
is an error.
Types
Functions
Result pipe operator.
The result pipe operator &&&/2
is a result-aware analogue to the pipe operator |>
.
It allows chaining functions that return results, piping the inner value of :ok
results
and short-circuiting the pipeline if any of the functions return an error. For example
with {:ok, x1} <- f1(x),
{:ok, x2} <- f2(x1) do
f3(x2)
end
can be written as
x |> f1() &&& f2() &&& f3()
More examples:
iex> {:ok, :foo} &&& Atom.to_string()
"foo"
iex> {:ok, 3} &&& then(fn x -> {:ok, x + 1} end) &&& List.wrap()
[4]
iex> {:ok, :foo} &&& Atom.to_string() |> String.capitalize()
"Foo"
iex> {:error, :oops} &&& Atom.to_string() |> String.capitalize()
{:error, :oops}
@spec and_then(t(v, e), (v -> w)) :: w | {:error, e} when v: var, w: var, e: var
Collects a list of results into a single result.
If any of the results is an error, the first error is returned. Otherwise, a single ok result is returned with a list of the result values.
iex> [{:ok, 1}, {:ok, 2}, {:ok, 3}] |> Result.collect()
{:ok, [1, 2, 3]}
iex> [{:ok, 1}, {:error, 2}, {:ok, 3}, {:error, 4}] |> Result.collect()
{:error, 2}
@spec err_if_nil(v | nil, e) :: t(v, e) when v: var, e: var
Convert a maybe-nil value to a result.
Maps nil
to {:error, reason}
and any non-nil
value to {:ok, value}
.
iex> %{"key" => "value"} |> Map.get("key") |> Result.err_if_nil(:notfound)
{:ok, "value"}
iex> %{"key" => "value"} |> Map.get("missing") |> Result.err_if_nil(:notfound)
{:error, :notfound}
@spec error(e) :: {:error, e} when e: var
Wrap a value in an error result.
iex> :some_error_reason |> Result.error()
{:error, :some_error_reason}
Return whether a result is an error.
iex> Result.is_error?({:ok, 3})
false
iex> Result.is_error?({:error, 3})
true
Return whether a result is ok.
iex> Result.is_ok?({:ok, 3})
true
iex> Result.is_ok?({:error, 3})
false
Return a result leaving errors unchanged but transforming the value of an :ok
result.
iex> Result.map({:ok, 3}, fn x -> x + 1 end)
{:ok, 4}
iex> Result.map({:error, :nan}, fn x -> x + 1 end)
{:error, :nan}
Return a result leaving ok values unchanged but transforming an error reason with f
.
iex> Result.map_err({:ok, 3}, fn x -> x + 1 end)
{:ok, 3}
iex> Result.map_err({:error, :nan}, &:erlang.atom_to_binary/1)
{:error, "nan"}
Return an unwrapped ok value transformed by f, or default
if result
is an error.
iex> Result.map_or({:ok, 3}, 0, fn x -> x + 1 end)
4
iex> Result.map_or({:error, :nan}, 0, fn x -> x + 1 end)
0
@spec ok(v) :: {:ok, v} when v: var
Wrap a value in an ok result.
@spec or_else(t(v, e), (e -> f)) :: {:ok, v} | f when e: var, f: var, v: var
Return an ok result unchanged, or transform an unwrapped error reason with f
.
iex> Result.or_else({:ok, :xylophone}, fn err -> err + 1 end)
{:ok, :xylophone}
iex> Result.or_else({:error, 3}, fn err -> err + 1 end)
4
Equivalent to Kernel.tap/2
for error results.
Calls f
with the reason of an :error
result, and returns the result unchanged.
iex> {:ok, 3} |> Result.tap_err(&IO.inspect/1)
{:ok, 3}
iex> {:error, :oops} |> Result.tap_err(&IO.inspect/1)
:oops
{:error, :oops}
Equivalent to Kernel.tap/2
for ok results.
Calls f
with the value of an :ok
result, and returns the result unchanged.
iex> {:ok, 3} |> Result.tap_ok(&IO.inspect/1)
3
{:ok, 3}
iex> {:error, :oops} |> Result.tap_ok(&IO.inspect/1)
{:error, :oops}
@spec unwrap!(t(v)) :: v when v: var
Unwrap an :ok
result, and raise an :error
reason.
iex> Result.unwrap!({:ok, :value})
:value
iex> Result.unwrap!({:error, "message"})
** (RuntimeError) message
@spec unwrap_or(t(v), w) :: v | w when w: var, v: var
Unwrap an :ok
result, falling back to default
for an :error
result.
iex> Result.unwrap_or({:ok, :cake}, :icecream)
:cake
iex> Result.unwrap_or({:error, :peas}, :icecream)
:icecream
@spec unwrap_or_else(t(v), (-> w)) :: v | w when w: var, v: var
Unwrap an :ok
result, falling back to executing a zero-arity function if the result
is an error.
iex> Result.unwrap_or_else({:ok, :cake}, fn -> :icecream end)
:cake
iex> Result.unwrap_or_else({:error, :peas}, fn -> :icecream end)
:icecream