bubblewrap v0.4.3 Bubblewrap.Result

Result module provides Result type with utility functions.

Link to this section Summary

Types

Result type. {:ok, res} or {:error, err} unwraps into {:ok, res} or {:error, err}

Functions

Filters and unwraps the collection of results, leaving only errors

Filters and unwraps the collection of results, leaving only ok's

Returns self if it is {:ok, x}, or evaluates supplied lambda that expected to return another result. Returns supplied fallback result, if second argument is not a function

Applies function that returns a boolean using the value of the monadic type. If false, the value will be set to the given error value

Applies function that returns monadic type itself to the content of the monadic type. This is useful in a chain of operations, where argument to the next op has to be unwrapped to proceed

Performs a calculation with the content of monadic container and returns the argument intact. Even though the convention says to return nothing (Unit) this one passes value along for convenience — this way we can perform more than one operation

Returns true if argument is error(), false if ok()

Returns true if argument is ok(), false if error()

Transforms the content of monadic type. Function is applied only if it's ok. Otherwise value stays intact

Groups and unwraps the collection of results, forming a Map with keys :ok and :error

Retry in case of error

Wraps expression and returns exception wrapped into {:error, _} if it happens, otherwise {:ok, result of expression}, in case if expression returns result type, it won't be wrapped

Returns value x if argument is {:ok, x}, raises e if {:error, e}. Second argument is a fallback. It can by a lambda accepting error, or some precomputed default value

Converts Result into Option: {:ok, val} -> val, {:error, e} -> nil. Useful when you don't care about the error value and only what to emphasize that nothing has been found

Always returns a Result, transforming a plain value to {:ok, x} if it isn't a result already

Link to this section Types

Link to this type

t(res, err)
t(res, err) :: {:ok, res} | {:error, err}

Result type. {:ok, res} or {:error, err} unwraps into {:ok, res} or {:error, err}

Link to this section Functions

Link to this function

collect_error(results)
collect_error([t(res, err)]) :: [err] when res: any(), err: any()

Filters and unwraps the collection of results, leaving only errors:

Examples

iex> [{:ok, 1}, {:error, "oops"}] |> collect_error
["oops"]
Link to this function

collect_ok(results)
collect_ok([t(res, any())]) :: [res] when res: any()

Filters and unwraps the collection of results, leaving only ok's

Examples

iex> [{:ok, 1}, {:error, "oops"}] |> collect_ok
[1]
Link to this function

fallback(arg, f)
fallback(t(res, err), t(res, err) | (err -> t(res, err))) ::
  t(res, err)
when res: any(), err: any()

Returns self if it is {:ok, x}, or evaluates supplied lambda that expected to return another result. Returns supplied fallback result, if second argument is not a function.

Examples

iex> {:ok, 5} |> fallback(fn _ -> 1 end)
{:ok, 5}

iex> {:error, "WTF"} |> fallback(fn m -> {:ok, "#{m}LOL"} end)
{:ok, "WTFLOL"}

iex> {:error, "WTF"} |> fallback({:ok, 5})
{:ok, 5}
Link to this function

filter(err, f, fe)
filter(t(a, e1), (a -> boolean()), (a -> e2) | e2) :: t(a, e1 | e2)
when a: any(), e1: any(), e2: any()

Applies function that returns a boolean using the value of the monadic type. If false, the value will be set to the given error value.

Example:

f = fn (x) ->
    x == 0
  end

{:ok, 5} |> filter(f) == {:ok, 5}
0 |> filter(f) == nil
Link to this function

flat_map(arg, f)
flat_map(t(a, b), (a -> t(c, b))) :: t(c, b)
when a: any(), b: any(), c: any()

Applies function that returns monadic type itself to the content of the monadic type. This is useful in a chain of operations, where argument to the next op has to be unwrapped to proceed.

Example:

f = fn (x) ->
  {:ok, x * 2}
end
{:ok, 5} |> flat_map(f) == {:ok, 10}
{:error, "fail"} |> flat_map(f) == {:error, "fail"}
Link to this function

foreach(res, f)
foreach(t(a, b), (a -> no_return())) :: t(a, b) when a: any(), b: any()

Performs a calculation with the content of monadic container and returns the argument intact. Even though the convention says to return nothing (Unit) this one passes value along for convenience — this way we can perform more than one operation.

{:ok, 5}
|> foreach(fn x -> IO.inspect(x) end)
|> foreach(fn x -> IO.inspect(2 * x) end)

This will print: 5 10

Link to this function

is_error(x)
is_error(t(any(), any())) :: boolean()

Returns true if argument is error(), false if ok()

Examples

iex> is_error({:error, "Error"})
true

iex> is_ok({:error, "Error"})
false
Link to this function

is_ok(arg)
is_ok(t(any(), any())) :: boolean()

Returns true if argument is ok(), false if error()

Examples

iex> is_ok({:ok, 5})
true

iex> is_error({:ok, 5})
false
Link to this function

map(arg, f)
map(t(a, b), (a -> c)) :: t(c, b) when a: any(), b: any(), c: any()

Transforms the content of monadic type. Function is applied only if it's ok. Otherwise value stays intact.

Example:

f = fn (x) ->
  x * 2
end
{:ok, 5} |> map(f) == {:ok, 10}
{:error, "fail"} |> map(f) == {:error, "fail"}
Link to this function

partition(results)
partition([t(res, err)]) :: %{ok: [res], error: [err]}
when res: any(), err: any()

Groups and unwraps the collection of results, forming a Map with keys :ok and :error:

Examples

iex> [{:ok, 1}, {:error, "oops"}, {:ok, 2}] |> partition
%{ok: [1, 2], error: ["oops"]}

iex> [{:ok, 1}] |> partition
%{ok: [1], error: []}
Link to this macro

retry(opts \\ [], list) (macro)

Retry in case of error.

Possible options:

  • :n - times to retry
  • :delay — delay between retries

Examples

result = retry n: 3, delay: 3000 do
  remote_service()
end

This will call remove_service() 4 times (1 time + 3 retries) with an interval of 3 seconds.

Link to this macro

try_result(mode \\ :full, list) (macro)

Wraps expression and returns exception wrapped into {:error, _} if it happens, otherwise {:ok, result of expression}, in case if expression returns result type, it won't be wrapped.

Possible modes:

  • :full - returns exception struct intact (default)
  • :message — returns error message only
  • :module — returns error module only

Examples

iex> try_result do
...>   5 + 5
...> end
{:ok, 10}

iex> broken = fn -> raise ArithmeticError, [message: "bad argument"] end
...> try_result do
...>   broken.()
...> end
{:error, %ArithmeticError{message: "bad argument"}}

...> try_result :message do
...>   broken.()
...> end
{:error, "bad argument"}

...> try_result :module do
...>   broken.()
...> end
{:error, ArithmeticError}
Link to this function

unwrap(result, fallback \\ nil)
unwrap(t(res, err), res | (err -> res)) :: res when res: any(), err: any()

Returns value x if argument is {:ok, x}, raises e if {:error, e}. Second argument is a fallback. It can by a lambda accepting error, or some precomputed default value.

Examples

iex> unwrap({:ok, 5})
5

iex> unwrap({:error, :uh_oh}, fn _ -> 10 end)
10

iex> unwrap({:error, :uh_oh}, 10)
10
Link to this function

unwrap_option(arg)
unwrap_option(t(res, any())) :: Bubblewrap.Option.t(res) when res: any()

Converts Result into Option: {:ok, val} -> val, {:error, e} -> nil. Useful when you don't care about the error value and only what to emphasize that nothing has been found.

Examples

iex> unwrap_option({:ok, 5})
5

iex> unwrap_option({:error, :uh_oh})
nil
Link to this function

wrap(result_or_value)
wrap(t(res, err) | res) :: res when res: any(), err: any()

Always returns a Result, transforming a plain value to {:ok, x} if it isn't a result already.

Examples

iex> wrap({:ok, 5})
{:ok, 5}

iex> wrap(5)
{:ok, 5}

iex> wrap({:error, :uh_oh})
{:error, :uh_oh}