Dx.Result (dx v0.3.5)
View SourceResult types and helpers to work with them.
A result is either:
{:error, e}if an error occurred{:not_loaded, data_reqs}if the result could not be determined without loading more data{:ok, boolean, binds}otherwise, in contexts where a boolean is expected (typet:b()){:ok, result, binds}otherwise, whereresultcan be any value (typet:v())
Data loading
In general, {:not_loaded, all_reqs} only ever returns data requirements that are really needed.
Example using all
For example, using all?/1 with 3 conditions A, B and C, where
iex> [
...> {:ok, true, %{}}, # A
...> {:not_loaded, [1]}, # B
...> {:ok, false, %{}}, # C
...> ]
...> |> Dx.Result.all?()
{:ok, false, %{}}The overall result is {:ok, false, %{}}.
While B would need more data to be loaded, C can already determined and is false,
so and any additional data loaded will not change that.
Example using find
Another example, using find/1 with 5 conditions A, B, C, D and E, where
iex> [
...> {:ok, false, %{}}, # A
...> {:not_loaded, [1]}, # B
...> {:not_loaded, [2]}, # C
...> {:ok, true, %{}}, # D
...> {:not_loaded, [3]}, # E
...> ]
...> |> Dx.Result.find()
{:not_loaded, [1, 2]}The overall result is {:not_loaded, data_reqs1 + data_reqs2}.
While D can already be determined and is {:ok, true, %{}}, B and C come first and need more data
to be loaded, so they can be determined and returned if either is {:ok, true, %{}} first.
All data requirements that might be needed are returned together in the result (those of B and C),
while those of E can be ruled out, as D already returns {:ok, true, %{}} and comes first.
Summary
Functions
Returns {:ok, true} if fun evaluates to {:ok, true} for all elements in enum.
Otherwise, returns {:not_loaded, data_reqs} if any yield that.
Otherwise, returns {:ok, false}.
Returns {:ok, true, binds} if fun evaluates to {:ok, true, binds} for any element in enum.
Otherwise, returns {:not_loaded, data_reqs} if any yields that.
Otherwise, returns {:ok, false, %{}}.
If ok, binds the result to the given key and returns the updated tuple. Otherwise, returns first argument as is.
Returns the number of elements for which fun evaluates to {:ok, true}.
If any elements return {:not_loaded, data_reqs}, returns all of them combined as {:not_loaded, ...}.
Otherwise, returns {:ok, default}.
Returns the number of elements before fun evaluates to {:ok, false} or an element is nil.
Elements are skipped (not counted) whenever fun evaluates to {:ok, :skip}.
If any elements before that return {:not_loaded, data_reqs}, returns all of them combined as {:not_loaded, ...}.
Otherwise, returns {:ok, default}.
Returns {:ok, elem} for the first elem for which fun evaluates to {:ok, true}.
If any elements before that return {:not_loaded, data_reqs}, returns all of them combined as {:not_loaded, ...}.
Otherwise, returns {:ok, default}.
Converts 2-tuples to the internal 3-tuple result format (type t:v() or t:b()).
Returns {:ok, mapped_results, binds} if all elements map to {:ok, result, binds}.
Otherwise, returns {:error, e} on error, or {:not_loaded, data_reqs} with all data requirements.
Returns {:ok, new_keyword_list, binds} with new values if all values map to {:ok, new_value, binds}.
Otherwise, returns {:error, e} on error, or {:not_loaded, data_reqs} with all data requirements.
Returns {:ok, new_map, binds} with new values if all values map to {:ok, new_value, binds}.
Otherwise, returns {:error, e} on error, or {:not_loaded, data_reqs} with all data requirements.
Wraps a value in an :ok result.
When given {:ok, value, binds}, runs fun on value and returns the result.
Otherwise, returns first argument as is.
Converts the internal 3-tuple result format (type t:v() or t:b()) to a 2-tuple format.
When given {:ok, value, binds}, runs fun on value and returns {:ok, new_value, binds}.
Otherwise, returns first argument as is.
When given {:ok, value, binds} or {:ok, value}, returns value.
Otherwise, raises an exception.
Wraps a value in a compatible tuple for use with this module, if it's not wrapped already.
Types
Possible return values from conditions.
Possible return values from resolving predicates.
Functions
Returns {:ok, true} if fun evaluates to {:ok, true} for all elements in enum.
Otherwise, returns {:not_loaded, data_reqs} if any yield that.
Otherwise, returns {:ok, false}.
Examples
iex> [
...> {:ok, true, %{}},
...> {:not_loaded, []},
...> {:ok, false, %{}},
...> ]
...> |> Dx.Result.all?()
{:ok, false, %{}}
iex> [
...> {:ok, true, %{}},
...> {:not_loaded, []},
...> {:ok, true, %{}},
...> ]
...> |> Dx.Result.all?()
{:not_loaded, []}
iex> [
...> {:ok, true, %{}},
...> {:ok, true, %{}},
...> ]
...> |> Dx.Result.all?()
{:ok, true, %{}}
Returns {:ok, true, binds} if fun evaluates to {:ok, true, binds} for any element in enum.
Otherwise, returns {:not_loaded, data_reqs} if any yields that.
Otherwise, returns {:ok, false, %{}}.
Examples
iex> [
...> {:ok, true, %{a: 1}},
...> {:not_loaded, []},
...> {:ok, false, %{}},
...> ]
...> |> Dx.Result.any?()
{:ok, true, %{a: 1}}
iex> [
...> {:ok, false, %{}},
...> {:not_loaded, []},
...> {:ok, false, %{}},
...> ]
...> |> Dx.Result.any?()
{:not_loaded, []}
iex> [
...> {:ok, false, %{}},
...> {:ok, false, %{}},
...> ]
...> |> Dx.Result.any?()
{:ok, false, %{}}
If ok, binds the result to the given key and returns the updated tuple. Otherwise, returns first argument as is.
Returns the number of elements for which fun evaluates to {:ok, true}.
If any elements return {:not_loaded, data_reqs}, returns all of them combined as {:not_loaded, ...}.
Otherwise, returns {:ok, default}.
Examples
iex> [
...> {:ok, true, %{}},
...> {:ok, false, %{}},
...> {:ok, true, %{}},
...> ]
...> |> Dx.Result.count()
{:ok, 2, %{}}
iex> [
...> {:ok, false, %{}},
...> {:not_loaded, [1]},
...> {:not_loaded, [2]},
...> {:ok, true, %{}},
...> {:not_loaded, [3]},
...> ]
...> |> Dx.Result.count()
{:not_loaded, [1, 2, 3]}
iex> [
...> {:ok, true, %{}},
...> {:ok, :skip, %{}},
...> {:ok, false, %{}},
...> {:ok, false, %{}},
...> ]
...> |> Dx.Result.count()
{:ok, 1, %{}}
iex> [
...> false,
...> false,
...> ]
...> |> Dx.Result.count(&{:ok, not &1, %{}})
{:ok, 2, %{}}
Returns the number of elements before fun evaluates to {:ok, false} or an element is nil.
Elements are skipped (not counted) whenever fun evaluates to {:ok, :skip}.
If any elements before that return {:not_loaded, data_reqs}, returns all of them combined as {:not_loaded, ...}.
Otherwise, returns {:ok, default}.
Examples
iex> [
...> {:ok, true, %{}},
...> {:not_loaded, []},
...> {:ok, false, %{}},
...> ]
...> |> Dx.Result.count_while()
{:not_loaded, []}
iex> [
...> {:ok, false, %{}},
...> {:not_loaded, [1]},
...> {:not_loaded, [2]},
...> {:ok, true, %{}},
...> {:not_loaded, [3]},
...> ]
...> |> Dx.Result.count_while()
{:ok, 0, %{}}
iex> [
...> {:ok, true, %{}},
...> {:ok, :skip, %{}},
...> {:ok, false, %{}},
...> {:ok, false, %{}},
...> ]
...> |> Dx.Result.count_while()
{:ok, 1, %{}}
iex> [
...> false,
...> false,
...> ]
...> |> Dx.Result.count_while(&{:ok, not &1, %{}})
{:ok, 2, %{}}
Returns {:ok, elem} for the first elem for which fun evaluates to {:ok, true}.
If any elements before that return {:not_loaded, data_reqs}, returns all of them combined as {:not_loaded, ...}.
Otherwise, returns {:ok, default}.
Examples
iex> [
...> {:ok, true, %{}},
...> {:not_loaded, []},
...> {:ok, false, %{}},
...> ]
...> |> Dx.Result.find()
{:ok, {:ok, true, %{}}, %{}}
iex> [
...> {:ok, false, %{}},
...> {:not_loaded, [1]},
...> {:not_loaded, [2]},
...> {:ok, true, %{}},
...> {:not_loaded, [3]},
...> ]
...> |> Dx.Result.find()
{:not_loaded, [1, 2]}
iex> [
...> {:ok, false, %{}},
...> {:ok, false, %{}},
...> ]
...> |> Dx.Result.find()
{:ok, nil, %{}}
iex> [
...> false,
...> false,
...> ]
...> |> Dx.Result.find(&{:ok, not &1, %{}})
{:ok, false, %{}}
Converts 2-tuples to the internal 3-tuple result format (type t:v() or t:b()).
Examples
iex> {:ok, 5}
...> |>Dx.Result.from_simple()
{:ok, 5, %{}}
iex> {:error, :err}
...> |>Dx.Result.from_simple()
{:error, :err}
Returns {:ok, mapped_results, binds} if all elements map to {:ok, result, binds}.
Otherwise, returns {:error, e} on error, or {:not_loaded, data_reqs} with all data requirements.
Examples
iex> [
...> {:ok, 1, %{}},
...> {:ok, 2, %{}},
...> {:ok, 3, %{}},
...> ]
...> |> Dx.Result.map()
{:ok, [1, 2, 3], %{}}
iex> [
...> {:ok, 1, %{}},
...> {:not_loaded, [:x]},
...> {:ok, 3, %{}},
...> {:not_loaded, [:y]},
...> ]
...> |> Dx.Result.map()
{:not_loaded, [:x, :y]}
iex> [
...> {:ok, 1, %{}},
...> {:error, :x},
...> {:ok, 3, %{}},
...> {:not_loaded, [:y]},
...> ]
...> |> Dx.Result.map()
{:error, :x}
Returns {:ok, new_keyword_list, binds} with new values if all values map to {:ok, new_value, binds}.
Otherwise, returns {:error, e} on error, or {:not_loaded, data_reqs} with all data requirements.
Examples
iex> [
...> a: {:ok, 1, %{}},
...> b: {:ok, 2, %{}},
...> c: {:ok, 3, %{}},
...> ]
...> |> Dx.Result.map_keyword_values()
{:ok, [a: 1, b: 2, c: 3], %{}}
iex> [
...> a: {:ok, 1, %{}},
...> b: {:not_loaded, MapSet.new([:x])},
...> c: {:ok, 3, %{}},
...> d: {:not_loaded, MapSet.new([:y])},
...> ]
...> |> Dx.Result.map_keyword_values()
{:not_loaded, MapSet.new([:x, :y])}
iex> [
...> a: {:ok, 1, %{}},
...> b: {:error, :x},
...> c: {:ok, 3, %{}},
...> d: {:not_loaded, [:y]},
...> ]
...> |> Dx.Result.map_keyword_values()
{:error, :x}
Returns {:ok, new_map, binds} with new values if all values map to {:ok, new_value, binds}.
Otherwise, returns {:error, e} on error, or {:not_loaded, data_reqs} with all data requirements.
Examples
iex> %{
...> a: {:ok, 1, %{}},
...> b: {:ok, 2, %{}},
...> c: {:ok, 3, %{}},
...> }
...> |> Dx.Result.map_values()
{:ok, %{a: 1, b: 2, c: 3}, %{}}
iex> %{
...> a: {:ok, 1, %{}},
...> b: {:not_loaded, MapSet.new([:x])},
...> c: {:ok, 3, %{}},
...> d: {:not_loaded, MapSet.new([:y])},
...> }
...> |> Dx.Result.map_values()
{:not_loaded, MapSet.new([:x, :y])}
iex> %{
...> a: {:ok, 1, %{}},
...> b: {:error, :x},
...> c: {:ok, 3, %{}},
...> d: {:not_loaded, [:y]},
...> }
...> |> Dx.Result.map_values()
{:error, :x}
Wraps a value in an :ok result.
When given {:ok, value, binds}, runs fun on value and returns the result.
Otherwise, returns first argument as is.
Converts the internal 3-tuple result format (type t:v() or t:b()) to a 2-tuple format.
Examples
iex> {:ok, 5, %{}}
...> |>Dx.Result.to_simple()
{:ok, 5}
iex> {:error, :err}
...> |>Dx.Result.to_simple()
{:error, :err}
When given {:ok, value, binds}, runs fun on value and returns {:ok, new_value, binds}.
Otherwise, returns first argument as is.
When given {:ok, value, binds} or {:ok, value}, returns value.
Otherwise, raises an exception.
Examples
iex> Dx.Result.unwrap!({:error, %ArgumentError{}})
** (ArgumentError) argument error
iex> Dx.Result.unwrap!({:error, :not_an_exception})
** (Dx.Error.Generic) Error occurred: :not_an_exception
Wraps a value in a compatible tuple for use with this module, if it's not wrapped already.