View Source Oxide.Result (oxide v0.3.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.

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.

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

@type t() :: {:ok, any()} | {:error, any()}
@type t(v) :: {:ok, v} | {:error, any()}
@type t(v, e) :: {:ok, v} | {:error, e}

Functions

Link to this macro

left &&& right

View Source (macro)

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()
@spec and_then(t(), (any() -> any())) :: any()
Link to this function

err_if_nil(value, reason)

View Source
@spec err_if_nil(any(), any()) :: t()

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(any()) :: t()

Wrap a value in an error result.

iex> :some_error_reason |> Result.error()
{:error, :some_error_reason}
@spec is_error?(t()) :: boolean()

Return whether a result is an error.

iex> Result.is_error?({:ok, 3})
false
iex> Result.is_error?({:error, 3})
true
@spec is_ok?(t()) :: boolean()

Return whether a result is ok.

iex> Result.is_ok?({:ok, 3})
true
iex> Result.is_ok?({:error, 3})
false
@spec map(t(), (any() -> any())) :: t()

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}
@spec map_err(t(), (any() -> any())) :: t()

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"}
Link to this function

map_or(result, default, f)

View Source
@spec map_or(t(), any(), (any() -> any())) :: any()

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(any()) :: t()

Wrap a value in an ok result.

@spec tap_err(t(), (any() -> any())) :: t()

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}
@spec tap_ok(t(), (any() -> any())) :: t()

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()) :: any()

Unwrap an :ok result, and raise an :error reason.

iex> Result.unwrap!({:ok, :value})
:value
iex> Result.unwrap!({:error, "message"})
** (RuntimeError) message
@spec unwrap_err!(t()) :: any()
Link to this function

unwrap_or(result, default)

View Source
@spec unwrap_or(t(), any()) :: any()

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
Link to this function

unwrap_or_else(result, f)

View Source
@spec unwrap_or_else(t(), (-> any())) :: any()

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