plymio_option v0.3.0 Plymio.Option.Utility View Source
Utility Function for Managing (Keyword) Options (“opts”)
Documentation Terms
In the documentation there are terms, usually in italics, used to mean the same thing (e.g. opts).
opts
opts is a Keyword
.
derivable opts
derivable opts is either a Keyword
or Map
with Atom
keys (from which the opts can be derived simply using Map.to_list/1
).
key
A key is an Atom
.
key list
A key list is a list of keys.
key spec
A key spec is usually a key list.
Alternatively a Map
with Atom
keys or a Keyword
can be given and the (unique) keys will be used.
key alias dict
A key alias dict is usually a Map
with Atom
keys and values used for canonicalising keys (e.g. as the 2nd argument to opts_canonical_keys/2
).
Alternatively a Keyword
with Atom
values can be given and will be converted on the fly.
key dict
A key alias dict is usually a Map
with Atom
keys.
Alternatively a Keyword
with Atom
values can be given and will be converted on the fly.
tuple predicate
A tuple predicate is an arity one function that when passed a {key,value}
tuple returns true
or false
.
Return Values
Many functions support an API that returns either {:ok, result}
or {:error, error}
where error
will be an Exception
.
The default action for bang function when fielding {:error, error}
is to raise the error
.
In many cases the error
will be a KeyError
where its key
field is set to the key, or list of keys, that is missing, unknown, etc.
Link to this section Summary
Functions
canon_keys/2
takes a key list together with a lookup dictionary and replaces each key with its canonical value from the dictionary, returning {:ok, canon_keys}
canon_keys!/2
takes a key list together with a lookup dictionary and replaces each key with its canonical value from the dictionary. Unknown keys raise a KeyError
canonical_key/2
takes a key together with a key dict and replaces the key with its canonical value from the dictionary, returning {:ok, canonical_key}
canonical_key!/2
calls canonical_key/2
and if the result is {:ok, canonical_key}
returns canonical_key
canonical_keys/2
takes a key list and key alias dict and replaces each key with its canonical value from the dictionary, returning {:ok, canonical_keys}
canonical_keys!/2
calls canonical_keys/2
and if the result is {:ok, canonical_keys}
returns canonical_keys
list_wrap_flat_just/1
wraps a value (if not already a list), flattens and removes nils
at the first / top level
list_wrap_flat_just_uniq/1
wraps a value (if not already a list), flattens, removes nils
at
the first / top level, and deletes duplicates (using Enum.uniq/1
)
maybe_canon_keys/2
takes a key list together with a lookup dictionary and, if the key is in the dictionary, replaces it with its value. Unknown keys are passed through unchanged
opts_avoir_keys/2
takes an opts and a key spec
opts_avoir_keys!/2
calls opts_avoir_keys/2
and if the result is {:ok, opts}
, returns opts
opts_avoir_keys?/2
calls opts_avoir_keys/2
and if the result is {:ok, _}
, returns true
, else false
opts_canon_keys/2
takes an opts, together with either a dictionary (map) or (keyword) list of aliases
opts_canon_keys!/2
takes an opts, together with a lookup dictionary and replaces each key with its canonical value from the dictionary. Unknown keys raise a KeyError
opts_canonical_keys/2
takes a derivable opts, together with a key alias dict
opts_canonical_keys!/2
calls opts_canonical_keys/2
and if the result is {:ok, opts}
returns opts
opts_create_aliases_dict/1
does the same job as opts_create_aliases_tuples/1
but returns a key alias dict
opts_create_aliases_tuples/1
takes an opts where the keys are the canonical key names, and their values are zero (nil), one or more aliases for the canonical key
opts_create_defstruct/2
takes an opts, together with a defaults map, and returns an opts where each value if the value of the key in the defaults map (with default nil
)
opts_crue_defstruct/2
takes a derivable opts, together with a defaults map, and returns {:ok, opts}
where each value is the value of the key in the defaults map (with default nil
)
opts_crue_defstruct!/2
calls opts_crue_defstruct/2
and if the result is {:ok, opts}
returns opts
opts_drop_keys!/1
takes an opts, together with a key list and returns the opts without the supplied keys
opts_fetch_key_values/2
takes a derivable opts and a key and returns the values of the key as {:ok, values}
where values
will be a list
opts_fetch_key_values!/2
takes a derivable opts and a key and returns the values of the key as {:ok, values}
opts_filter/2
takes a derivable opts, together with a tuple predicate and returns {:ok, opts}
where opts
has all the 2tuples the tuple predicate return true
for
opts_filter!/2
calls opts_filter/2
and if the result is {:ok, opts}
returns opts
opts_filter_keys/2
takes a derivable opts and a key spec and returns {:ok, opts}
where opts
has all keys from the original derivable opts that appear in the key spec
opts_filter_keys!/2
calls opts_filter_keys/2
and if the result is {:ok, opts}
, returns opts
opts_has_keys/2
takes an opts, together with a list or dictionary (map) of wanted keys
opts_has_keys!/2
calls opts_has_keys/2
and if the result is {:ok, opts}
, returns opts
opts_has_keys?/2
calls opts_has_keys/2
and if the result is {:ok, _}
, returns true
, else false
opts_normalise/
expects a derivable opts and returns {:ok, opts}
opts_normalise!/1
calls opts_normalise/1
and if the result is {:ok, opts}
returns opts
opts_normalise_map/
expects a derivable opts as argument
opts_normalise_map!/1
call opts_normalise_map/1
and if the result is {:ok, map}
returns map
opts_predicate/2
takes a derivable opts, together with a tuple predicate and returns {:ok, opts}
if all the 2tuples pass the tuple predicate
opts_predicate!/2
calls opts_predicate/2
and if the result is {:ok, opts}
returns opts
opts_reject/2
takes a derivable opts, together with a tuple predicate and returns {:ok, opts}
where opts
has all the 2tuples the tuple predicate returns false
for
opts_reject!/2
calls opts_reject/2
and if the result is {:ok, opts}
returns opts
opts_reject_keys/2
takes a derivable opts and a key spec and returns {:ok, opts}
where opts
has all keys from the original derivable opts that do not appear in the key spec
opts_reject_keys!/2
calls opts_reject_keys/2
and if the result is {:ok, opts}
, returns opts
opts_sort_keys/
takes a derivable opts, together with a list of sort keys, and returns the opts sorted in the sort keys order. Duplicate keys follow one after another
opts_take_keys!/1
takes an opts, together with a key list and returns the opts with just the supplied keys
opts_validate/1
returns {:ok, opts}
if the argument is an opts
opts_validate!/1
calls opts_validate/1
and, if the result is {:ok, opts}
, returns opts
Link to this section Types
Link to this section Functions
canon_keys(alias_keys(), dict()) :: {:ok, alias_keys()} | {:error, error()}
canon_keys/2
takes a key list together with a lookup dictionary and replaces each key with its canonical value from the dictionary, returning {:ok, canon_keys}
.
If there are any unknown keys, {:error, {canon_known_keys, unknown_keys}}
will be returned.
Examples
iex> [:a, :b, :c] |> canon_keys(%{a: 1, b: 2, c: 3})
{:ok, [1,2,3]}
iex> [:a, :x, :b, :y, :c, :z] |> canon_keys(%{a: 1, b: 2, c: 3})
{:error, {[1, 2, 3], [:x, :y, :z]}}
canon_keys!(alias_keys(), dict()) :: alias_keys() | no_return()
canon_keys!/2
takes a key list together with a lookup dictionary and replaces each key with its canonical value from the dictionary. Unknown keys raise a KeyError
.
Examples
iex> [:a, :b, :c] |> canon_keys!(%{a: 1, b: 2, c: 3})
[1,2,3]
iex> [:x] |> canon_keys!(%{a: 1, b: 2, c: 3})
** (KeyError) key :x not found in: %{a: 1, b: 2, c: 3}
canonical_key/2
takes a key together with a key dict and replaces the key with its canonical value from the dictionary, returning {:ok, canonical_key}
.
If the key is unknown, {:error, error}
, error
is a KeyError
, will be returned.
Examples
iex> :b |> canonical_key(%{a: :p, b: :q, c: :r})
{:ok, :q}
iex> :a |> canonical_key(%{a: 1, b: 2, c: 3})
{:ok, 1}
iex> :x |> canonical_key(%{a: 1, b: 2, c: 3})
{:error, %KeyError{key: :x, term: %{a: 1, b: 2, c: 3}}}
canonical_key!/2
calls canonical_key/2
and if the result is {:ok, canonical_key}
returns canonical_key
.
Examples
iex> :a |> canonical_key!(%{a: 1, b: 2, c: 3})
1
iex> :b |> canonical_key!(%{a: :p, b: :q, c: :r})
:q
iex> :x |> canonical_key!(%{a: 1, b: 2, c: 3})
** (KeyError) key :x not found in: %{a: 1, b: 2, c: 3}
canonical_keys(alias_keys(), any()) :: {:ok, alias_keys()} | {:error, error()}
canonical_keys/2
takes a key list and key alias dict and replaces each key with its canonical value from the dictionary, returning {:ok, canonical_keys}
.
If there are any unknown keys {:error, error}
, where error
is a KeyError
, will be returned.
Examples
iex> [:a, :b, :c] |> canonical_keys(%{a: :p, b: :q, c: :r})
{:ok, [:p,:q,:r]}
iex> [:a, :b, :c] |> canonical_keys(%{a: 1, b: 2, c: 3})
{:ok, [1,2,3]}
iex> [:a, :x, :b, :y, :c, :z] |> canonical_keys(%{a: 1, b: 2, c: 3})
{:error, %KeyError{key: [:x, :y, :z], term: %{a: 1, b: 2, c: 3}}}
canonical_keys!(alias_keys(), dict()) :: alias_keys() | no_return()
canonical_keys!/2
calls canonical_keys/2
and if the result is {:ok, canonical_keys}
returns canonical_keys
.
Examples
iex> [:a, :b, :c] |> canonical_keys!(%{a: :p, b: :q, c: :r})
[:p,:q,:r]
iex> [:a, :b, :c] |> canonical_keys!(%{a: 1, b: 2, c: 3})
[1,2,3]
iex> [:a, :x, :b, :y, :c, :z] |> canonical_keys!(%{a: 1, b: 2, c: 3})
** (KeyError) key [:x, :y, :z] not found in: %{a: 1, b: 2, c: 3}
list_wrap_flat_just/1
wraps a value (if not already a list), flattens and removes nils
at the first / top level.
Examples
iex> [{:a, 1}, nil, [{:b1, 12}, nil, {:b2, [nil, 22, nil]}], nil, {:c, 3}] |> list_wrap_flat_just
[a: 1, b1: 12, b2: [nil, 22, nil], c: 3]
iex> [[[nil, 42, nil]]] |> list_wrap_flat_just
[42]
list_wrap_flat_just_uniq(any()) :: [any()]
list_wrap_flat_just_uniq/1
wraps a value (if not already a list), flattens, removes nils
at
the first / top level, and deletes duplicates (using Enum.uniq/1
)
Examples
iex> [{:a, 1}, nil, [{:b1, 12}, nil, {:b2, [nil, 22, nil]}], nil, {:c, 3}, {:a, 1}, {:b1, 12}] |> list_wrap_flat_just_uniq
[a: 1, b1: 12, b2: [nil, 22, nil], c: 3]
iex> [nil, [42, [42, 42, nil]], 42] |> list_wrap_flat_just_uniq
[42]
maybe_canon_keys(alias_keys(), dict()) :: alias_keys()
maybe_canon_keys/2
takes a key list together with a lookup dictionary and, if the key is in the dictionary, replaces it with its value. Unknown keys are passed through unchanged.
Examples
iex> [:a, :b, :c] |> maybe_canon_keys(%{a: 1, b: 2, c: 3})
[1, 2, 3]
iex> [:x, :a] |> maybe_canon_keys(%{a: 1, b: 2, c: 3})
[:x, 1]
opts_avoir_keys/2
takes an opts and a key spec.
If all of the keys are present in the opts
, its returns {:ok, opts}
.
If there are any missing keys, {:error, error}
, where error
is a KeyError
, will be returned.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_avoir_keys([:a, :b, :c])
{:ok, [a: 1, b: 2, c: 3]}
iex> [a: 1, b: 2, c: 3] |> opts_avoir_keys(%{a: 1, b: 2, c: 3})
{:ok, [a: 1, b: 2, c: 3]}
iex> [a: 1, b: 2, c: 3] |> opts_avoir_keys([:a, :b, :d, :a])
{:error, %KeyError{key: :d, term: [a: 1, b: 2, c: 3]}}
iex> [a: 1, b: 2, c: 3] |> opts_avoir_keys(%{x: nil, y: nil, z: nil})
{:error, %KeyError{key: [:x, :y, :z], term: [a: 1, b: 2, c: 3]}}
opts_avoir_keys!(any(), any()) :: opts() | no_return()
opts_avoir_keys!/2
calls opts_avoir_keys/2
and if the result is {:ok, opts}
, returns opts
.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_avoir_keys!([:a, :b, :c])
[a: 1, b: 2, c: 3]
iex> [a: 1, b: 2, c: 3] |> opts_avoir_keys!(%{a: 1, b: 2, c: 3})
[a: 1, b: 2, c: 3]
iex> [a: 1, b: 2, c: 3] |> opts_avoir_keys!([:a, :b, :d, :a])
** (KeyError) key :d not found in: [a: 1, b: 2, c: 3]
iex> [a: 1, b: 2, c: 3] |> opts_avoir_keys!(%{x: nil, y: nil, z: nil})
** (KeyError) key [:x, :y, :z] not found in: [a: 1, b: 2, c: 3]
opts_avoir_keys?(any(), any()) :: true | false
opts_avoir_keys?/2
calls opts_avoir_keys/2
and if the result is {:ok, _}
, returns true
, else false
.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_avoir_keys?([:a, :b, :c])
true
iex> [a: 1, b: 2, c: 3] |> opts_avoir_keys?(%{a: 1, b: 2, c: 3})
true
iex> [a: 1, b: 2, c: 3] |> opts_avoir_keys?([:a, :b, :d, :a])
false
iex> [a: 1, b: 2, c: 3] |> opts_avoir_keys?(%{x: nil, y: nil, z: nil})
false
opts_canon_keys/2
takes an opts, together with either a dictionary (map) or (keyword) list of aliases.
If a dictionary is provided, each key in the opts
is replaced with its (canonical) value from the dictionary, returning {:ok, transformed_opts}
.
If a (keyword) list of aliases is provided, the aliases are first converted into a dictionary by opts_create_aliases_dict/1
and the dictionary used as described above.
If there are any unknown keys, {:error, {known_opts, unknown_opts}}
is returned.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_canon_keys(%{a: :x, b: :y, c: :z})
{:ok, [x: 1, y: 2, z: 3]}
iex> [a: 11, p: 1, b: 22, q: 2, c: 33, r: 3] |> opts_canon_keys(%{a: :x, b: :y, c: :z})
{:error, {[x: 11, y: 22, z: 33], [p: 1, q: 2, r: 3]}}
iex> [a: 1, b: 2, c: 3] |> opts_canon_keys([a_canon: :a, b_canon: [:b], c_canon: [:c, :cc]])
{:ok, [a_canon: 1, b_canon: 2, c_canon: 3]}
iex> [a: 1, b: 2, c: 3] |> opts_canon_keys([a_canon: :a, b_canon: nil, c_canon: [:c, :cc]])
{:error, {[a_canon: 1, c_canon: 3], [b: 2]}}
opts_canon_keys!/2
takes an opts, together with a lookup dictionary and replaces each key with its canonical value from the dictionary. Unknown keys raise a KeyError
.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_canon_keys!(%{a: :x, b: :y, c: :z})
[x: 1, y: 2, z: 3]
iex> [x: 1, y: 3, z: 3] |> opts_canon_keys!(%{a: 1, b: 2, c: 3})
** (KeyError) key :x not found in: %{a: 1, b: 2, c: 3}
opts_canonical_keys/2
takes a derivable opts, together with a key alias dict.
Each key in the opts
is replaced with its (canonical) value from the dictionary, returning {:ok, canon_opts}
.
If there are any unknown keys, {:error, error}
, where error
is a KeyError
, will be returned.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_canonical_keys(%{a: :x, b: :y, c: :z})
{:ok, [x: 1, y: 2, z: 3]}
iex> [a: 1, b: 2, c: 3] |> opts_canonical_keys([a: :x, b: :y, c: :z])
{:ok, [x: 1, y: 2, z: 3]}
iex> [a: 11, p: 1, b: 22, q: 2, c: 33, r: 3] |> opts_canonical_keys(%{a: :x, b: :y, c: :z})
{:error, %KeyError{key: [:p, :q, :r], term: %{a: :x, b: :y, c: :z}}}
iex> [a: 1, b: 2, c: 3] |> opts_canonical_keys([a_canon: :a, b_canon: [:b], c_canon: [:c, :cc]])
{:error, %ArgumentError{message: "expected valid key alias dictionary; got: %{a_canon: :a, b_canon: [:b], c_canon: [:c, :cc]}"}}
opts_canonical_keys!(any(), any()) :: opts() | no_return()
opts_canonical_keys!/2
calls opts_canonical_keys/2
and if the result is {:ok, opts}
returns opts
.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_canonical_keys!(%{a: :x, b: :y, c: :z})
[x: 1, y: 2, z: 3]
iex> [a: 1, b: 2, c: 3] |> opts_canonical_keys!([a: :x, b: :y, c: :z])
[x: 1, y: 2, z: 3]
iex> [x: 1, y: 3, z: 3] |> opts_canonical_keys!(%{a: 1, b: 2, c: 3})
** (ArgumentError) expected valid key alias dictionary; got: %{a: 1, b: 2, c: 3}
opts_create_aliases_dict(aliases_kvs()) :: aliases_dict()
opts_create_aliases_dict/1
does the same job as opts_create_aliases_tuples/1
but returns a key alias dict.
Examples
iex> [a: nil, b: [:b1], c: [:c1, :c2, :c3]] |> opts_create_aliases_dict
%{a: :a, b: :b, b1: :b, c: :c, c1: :c, c2: :c, c3: :c}
opts_create_aliases_tuples(aliases_kvs()) :: aliases_tuples()
opts_create_aliases_tuples/1
takes an opts where the keys are the canonical key names, and their values are zero (nil), one or more aliases for the canonical key.
A Keyword
is returned where each key is an alias and its value the canonical key.
The canonical key also has an entry for itself with the same value.
Examples
iex> [a: nil, b: [:b1], c: [:c1, :c2, :c3]] |> opts_create_aliases_tuples
[a: :a, b: :b, b1: :b, c: :c, c1: :c, c2: :c, c3: :c]
opts_create_defstruct(opts(), defaults_map()) :: opts()
opts_create_defstruct/2
takes an opts, together with a defaults map, and returns an opts where each value if the value of the key in the defaults map (with default nil
).
opts_create_defstruct/2
creates an argument suitable for use with Kernel.defstruct/1
The defaults map must contain only keys that are also in the opts list; any unknown keys will raise a KeyError.
Examples
iex> [a: 1, b: :two, c: "tre", d: nil] |> opts_create_defstruct(%{a: 42, b: "two"})
[a: 42, b: "two", c: nil, d: nil]
iex> [a: 1, b: :two, c: "tre", d: nil] |> opts_create_defstruct(%{a: 42, b: "two", x: 1})
** (KeyError) key [:x] not found in: [a: 1, b: :two, c: "tre", d: nil]
opts_crue_defstruct(opts(), defaults_map()) :: {:ok, opts()} | {:error, error()}
opts_crue_defstruct/2
takes a derivable opts, together with a defaults map, and returns {:ok, opts}
where each value is the value of the key in the defaults map (with default nil
).
opts_crue_defstruct/2
creates an argument suitable for use with Kernel.defstruct/1
The defaults map must contain only keys that are also in the opts list; any unknown keys will cause {:error, error}
, where error
is a KeyError
, to be returned.
Examples
iex> [a: 1, b: :two, c: "tre", d: nil] |> opts_crue_defstruct(%{a: 42, b: "two"})
{:ok, [a: 42, b: "two", c: nil, d: nil]}
iex> [a: 1, b: :two, c: "tre", d: nil] |> opts_crue_defstruct(%{a: 42, b: "two", x: 1})
{:error, %KeyError{key: :x, term: [a: 1, b: :two, c: "tre", d: nil]}}
opts_crue_defstruct!(opts(), defaults_map()) :: opts() | no_return()
opts_crue_defstruct!/2
calls opts_crue_defstruct/2
and if the result is {:ok, opts}
returns opts
.
Examples
iex> [a: 1, b: :two, c: "tre", d: nil] |> opts_crue_defstruct!(%{a: 42, b: "two"})
[a: 42, b: "two", c: nil, d: nil]
iex> [a: 1, b: :two, c: "tre", d: nil] |> opts_crue_defstruct!(%{a: 42, b: "two", x: 1})
** (KeyError) key :x not found in: [a: 1, b: :two, c: "tre", d: nil]
See Keyword.drop/2
.
opts_drop_keys!/1
takes an opts, together with a key list and returns the opts without the supplied keys.
It any of the keys are not found, raises a KeyError
citing the missing keys.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_drop_keys!([:b])
[a: 1, c: 3]
iex> [a: 11, b: 21, c: 3, b: 22, a: 12] |> opts_drop_keys!([:b])
[a: 11, c: 3, a: 12]
iex> [a: 1, b: 2, c: 3] |> opts_drop_keys!([:d, :a])
** (KeyError) key [:d] not found in: [a: 1, b: 2, c: 3]
opts_fetch_key_values/2
takes a derivable opts and a key and returns the values of the key as {:ok, values}
where values
will be a list.
One of more indices can be provided to select the values at specific indices; the default is to return all values from Keyword.get_values/2
.
Note indices must be relative to the result of Keyword.get_values/2
not the indices of the original opts
Values are returned in the same order as the indices. Indices may be repeated. Indices are validated; asking for an unknown/impossible index will cause an error.
Examples
The default is to return all the values for a key i.e same as Keyword.get_values/2
:
iex> [a: 1, b: 2, c: 3] |> opts_fetch_key_values(:a)
{:ok, [1]}
This examples show multiple values being returned:
iex> [a: 11, b: 2, a: 12, c: 3, a: 13] |> opts_fetch_key_values(:a)
{:ok, [11, 12, 13]}
Here the last value for the key is returned:
iex> [a: 11, b: 2, a: 12, c: 3, a: 13] |> opts_fetch_key_values(:a, -1)
{:ok, [13]}
Here only the first value is wanted:
iex> [a: 11, b: 2, a: 12, c: 3, a: 13] |> opts_fetch_key_values(:a, 0)
{:ok, [11]}
Values at different indices:
iex> [a: 11, b: 2, a: 12, c: 3, a: 13] |> opts_fetch_key_values(:a, [1,-1])
{:ok, [12, 13]}
Note order of the values is same order as the indices:
iex> [a: 11, b: 2, a: 12, c: 3, a: 13] |> opts_fetch_key_values(:a, [-2,0,-1])
{:ok, [12, 11, 13]}
The same index/indices can be repeated:
iex> [a: 11, b: 2, a: 12, c: 3, a: 13] |> opts_fetch_key_values(:a, [-2,0,-2,-1,0])
{:ok, [12, 11, 12, 13, 11]}
Indices are validated:
iex> [a: 11, b: 2, a: 12, c: 3, a: 13] |> opts_fetch_key_values(:a, 99)
{:error, %ArgumentError{message: "index invalid; got: 99"}}
iex> [a: 11, b: 2, a: 12, c: 3, a: 13] |> opts_fetch_key_values(:a, :not_an_index)
{:error, %ArgumentError{message: "index invalid; got: :not_an_index"}}
opts_fetch_key_values!(any(), any(), any()) :: list() | no_return()
opts_fetch_key_values!/2
takes a derivable opts and a key and returns the values of the key as {:ok, values}
.
One of more indices can be provided to select the values at specific indices; the default is to return all values from Keyword.get_values/2
.
Note indices must be relative to the result of Keyword.get_values/2
not the indices of the original opts
Values are returned in the order they are given in the indices. Indices may be repeated.
Examples
The default is to return all the values for a key:
iex> [a: 1, b: 2, c: 3] |> opts_fetch_key_values!(:a)
[1]
This examples show multiple values being returned:
iex> [a: 11, b: 2, a: 12, c: 3, a: 13] |> opts_fetch_key_values!(:a)
[11, 12, 13]
Here the last value for the key is returned:
iex> [a: 11, b: 2, a: 12, c: 3, a: 13] |> opts_fetch_key_values!(:a, -1)
[13]
Here the first value is wanted:
iex> [a: 11, b: 2, a: 12, c: 3, a: 13] |> opts_fetch_key_values!(:a, 0)
[11]
Values at different indices:
iex> [a: 11, b: 2, a: 12, c: 3, a: 13] |> opts_fetch_key_values!(:a, [1,-1])
[12, 13]
Note order of the values is same as order of the indices
iex> [a: 11, b: 2, a: 12, c: 3, a: 13] |> opts_fetch_key_values!(:a, [-2,0,-1])
[12, 11, 13]
The same index/indices can be requested more than once:
iex> [a: 11, b: 2, a: 12, c: 3, a: 13] |> opts_fetch_key_values!(:a, [-2,0,-2,-1,0])
[12, 11, 12, 13, 11]
Indices are validated:
iex> [a: 11, b: 2, a: 12, c: 3, a: 13] |> opts_fetch_key_values!(:a, :not_an_index)
** (ArgumentError) index invalid; got: :not_an_index
opts_filter/2
takes a derivable opts, together with a tuple predicate and returns {:ok, opts}
where opts
has all the 2tuples the tuple predicate return true
for.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_filter(&(&1))
{:ok, [a: 1, b: 2, c: 3]}
iex> [a: 1, b: 2, c: 3] |> opts_filter(
...> fn
...> {:a,_} -> true
...> _ -> false
...> end)
{:ok, [a: 1]}
iex> %{a: 1, b: 2, c: 3} |> opts_filter(
...> fn
...> {:a,_} -> false
...> _ -> true
...> end)
{:ok, [b: 2, c: 3]}
iex> {:error, error} = [a: 1, b: 2, c: 3] |> opts_filter(:not_a_function)
...> match?(%ArgumentError{message: "expected valid tuple predicate; got: :not_a_function"}, error)
true
iex> {:error, error} = :not_opts |> opts_filter(&(&1))
...> match?(%ArgumentError{message: "expected valid derivable opts; got: :not_opts"}, error)
true
opts_filter!(any(), any()) :: opts() | no_return()
opts_filter!/2
calls opts_filter/2
and if the result is {:ok, opts}
returns opts
.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_filter!(&(&1))
[a: 1, b: 2, c: 3]
iex> [a: 1, b: 2, c: 3] |> opts_filter!(
...> fn
...> {:a,_} -> true
...> _ -> false
...> end)
[a: 1]
iex> %{a: 1, b: 2, c: 3} |> opts_filter!(
...> fn
...> {:a,_} -> false
...> _ -> true
...> end)
[b: 2, c: 3]
iex> [a: 1, b: 2, c: 3] |> opts_filter!(:not_a_function)
** (ArgumentError) expected valid tuple predicate; got: :not_a_function
iex> :not_opts |> opts_filter!(&(&1))
** (ArgumentError) expected valid derivable opts; got: :not_opts
opts_filter_keys/2
takes a derivable opts and a key spec and returns {:ok, opts}
where opts
has all keys from the original derivable opts that appear in the key spec.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_filter_keys([:a, :b, :c])
{:ok, [a: 1, b: 2, c: 3]}
iex> [a: 1, b: 2, c: 3] |> opts_filter_keys([b: :want_b, c: :and_c])
{:ok, [b: 2, c: 3]}
iex> [a: 1, b: 2, c: 3] |> opts_filter_keys(%{a: 42, b: nil})
{:ok, [a: 1, b: 2]}
iex> [a: 1, b: 2, c: 3] |> opts_filter_keys(:not_a_key_spec)
{:error, %ArgumentError{message: "expected enum; got: :not_a_key_spec"}}
iex> :not_opts |> opts_filter_keys([:a, :b, :c])
{:error, %ArgumentError{message: "expected valid derivable opts; got: :not_opts"}}
opts_filter_keys!(any(), any()) :: opts() | no_return()
opts_filter_keys!/2
calls opts_filter_keys/2
and if the result is {:ok, opts}
, returns opts
.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_filter_keys!([:a, :b, :c])
[a: 1, b: 2, c: 3]
iex> [a: 1, b: 2, c: 3] |> opts_filter_keys!([b: :want_b, c: :and_c])
[b: 2, c: 3]
iex> [a: 1, b: 2, c: 3] |> opts_filter_keys!(%{a: 42, b: nil})
[a: 1, b: 2]
iex> [a: 1, b: 2, c: 3] |> opts_filter_keys!(:not_a_key_spec)
** (ArgumentError) expected enum; got: :not_a_key_spec
iex> :not_opts |> opts_filter_keys!([:a, :b, :c])
** (ArgumentError) expected valid derivable opts; got: :not_opts
opts_has_keys/2
takes an opts, together with a list or dictionary (map) of wanted keys
.
If all of the keys
are present in the opts
, its returns {:ok, opts}
.
If there are any missing keys, {:error, {present_opts, missing_keys}}
is returned, where the
present_opts
include only the tuples for the wanted keys (i.e. result of Keyword.take/2
for the wanted keys).
Examples
iex> [a: 1, b: 2, c: 3] |> opts_has_keys([:a, :b, :c])
{:ok, [a: 1, b: 2, c: 3]}
iex> [a: 1, b: 2, c: 3] |> opts_has_keys(%{a: 1, b: 2, c: 3})
{:ok, [a: 1, b: 2, c: 3]}
iex> [a: 1, b: 2, c: 3] |> opts_has_keys([:a, :b, :d, :a])
{:error, {[a: 1, b: 2], [:d]}}
iex> [a: 1, b: 2, c: 3] |> opts_has_keys(%{x: nil, y: nil, z: nil})
{:error, {[], [:x, :y, :z]}}
opts_has_keys!/2
calls opts_has_keys/2
and if the result is {:ok, opts}
, returns opts
.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_has_keys!([:a, :b, :c])
[a: 1, b: 2, c: 3]
iex> [a: 1, b: 2, c: 3] |> opts_has_keys!(%{a: 1, b: 2, c: 3})
[a: 1, b: 2, c: 3]
iex> [a: 1, b: 2, c: 3] |> opts_has_keys!([:a, :b, :d, :a])
** (KeyError) key [:d] not found in: [a: 1, b: 2, c: 3]
iex> [a: 1, b: 2, c: 3] |> opts_has_keys!(%{x: nil, y: nil, z: nil})
** (KeyError) key [:x, :y, :z] not found in: [a: 1, b: 2, c: 3]
opts_has_keys?/2
calls opts_has_keys/2
and if the result is {:ok, _}
, returns true
, else false
.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_has_keys?([:a, :b, :c])
true
iex> [a: 1, b: 2, c: 3] |> opts_has_keys?(%{a: 1, b: 2, c: 3})
true
iex> [a: 1, b: 2, c: 3] |> opts_has_keys?([:a, :b, :d, :a])
false
iex> [a: 1, b: 2, c: 3] |> opts_has_keys?(%{x: nil, y: nil, z: nil})
false
opts_normalise/
expects a derivable opts and returns {:ok, opts}
.
Any other argument causes {:error, error}
to be returned.
Examples
iex> [] |> opts_normalise
{:ok, []}
iex> %{a: 1, b: 2, c: 3} |> opts_normalise
{:ok, [a: 1, b: 2, c: 3]}
iex> %{"a" => 1, :b => 2, :c => 3} |> opts_normalise
{:error, %KeyError{key: "a", term: %{:b => 2, :c => 3, "a" => 1}}}
iex> 42 |> opts_normalise
{:error, %ArgumentError{message: "expected valid derivable opts; got: 42"}}
iex> [a: nil, b: [:b1], c: [:c1, :c2, :c3]] |> opts_normalise
{:ok, [a: nil, b: [:b1], c: [:c1, :c2, :c3]]}
opts_normalise!(any()) :: opts() | no_return()
opts_normalise!/1
calls opts_normalise/1
and if the result is {:ok, opts}
returns opts
.
Examples
iex> [] |> opts_normalise!
[]
iex> %{a: 1, b: 2, c: 3} |> opts_normalise!
[a: 1, b: 2, c: 3]
iex> %{"a" => 1, :b => 2, :c => 3} |> opts_normalise!
** (KeyError) key "a" not found in: %{:b => 2, :c => 3, "a" => 1}
iex> 42 |> opts_normalise!
** (ArgumentError) expected valid derivable opts; got: 42
iex> [a: nil, b: [:b1], c: [:c1, :c2, :c3]] |> opts_normalise!
[a: nil, b: [:b1], c: [:c1, :c2, :c3]]
opts_normalise_map/
expects a derivable opts as argument.
If the argument is a Map
, with Atom
keys, it returns {:ok, argument}
directly.
If the argument is a Keyword
, with Atom
keys, it returns {:ok, argument |> Enum.into(%{})}
.
Any other argument causes {:error, error}
to be returned.
Examples
iex> [] |> opts_normalise_map
{:ok, %{}}
iex> [a: nil, b: [:b1], c: [:c1, :c2, :c3]] |> opts_normalise_map
{:ok, %{a: nil, b: [:b1], c: [:c1, :c2, :c3]}}
iex> %{a: 1, b: 2, c: 3} |> opts_normalise_map
{:ok, %{a: 1, b: 2, c: 3}}
iex> %{"a" => 1, :b => 2, :c => 3} |> opts_normalise_map
{:error, %KeyError{key: ["a"], term: %{:b => 2, :c => 3, "a" => 1}}}
iex> 42 |> opts_normalise_map
{:error, %ArgumentError{message: "expected valid derivable opts; got: 42"}}
opts_normalise_map!(any()) :: opts() | no_return()
opts_normalise_map!/1
call opts_normalise_map/1
and if the result is {:ok, map}
returns map
.
Examples
iex> [] |> opts_normalise_map!
%{}
iex> [a: 1, b: 2, c: 3] |> opts_normalise_map!
%{a: 1, b: 2, c: 3}
iex> %{a: 1, b: 2, c: 3} |> opts_normalise_map!
%{a: 1, b: 2, c: 3}
iex> %{"a" => 1, :b => 2, :c => 3} |> opts_normalise_map!
** (KeyError) key ["a"] not found in: %{:b => 2, :c => 3, "a" => 1}
iex> 42 |> opts_normalise_map!
** (ArgumentError) expected valid derivable opts; got: 42
opts_predicate/2
takes a derivable opts, together with a tuple predicate and returns {:ok, opts}
if all the 2tuples pass the tuple predicate.
If any of the opts fail the tuple predicate, {:error, error} is returned where error
will be a KeyError
whose key
field contains all the keys that failed.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_predicate(&(&1))
{:ok, [a: 1, b: 2, c: 3]}
iex> [a: 1, b: 2, c: 3] |> opts_predicate(fn {_k,v} -> v |> is_integer end)
{:ok, [a: 1, b: 2, c: 3]}
iex> [a: 1, b: 2, c: 3] |> opts_predicate(
...> fn
...> {:a,_} -> true
...> _ -> false
...> end)
{:error, %KeyError{key: [:b, :c], term: [a: 1, b: 2, c: 3]}}
iex> {:error, error} = [a: 1, b: 2, c: 3] |> opts_predicate(:not_a_function)
...> match?(%ArgumentError{message: "expected valid tuple predicate; got: :not_a_function"}, error)
true
iex> {:error, error} = :not_opts |> opts_predicate(&(&1))
...> match?(%ArgumentError{message: "expected valid derivable opts; got: :not_opts"}, error)
true
opts_predicate!(any(), any()) :: opts() | no_return()
opts_predicate!/2
calls opts_predicate/2
and if the result is {:ok, opts}
returns opts
.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_predicate(&(&1))
{:ok, [a: 1, b: 2, c: 3]}
iex> [a: 1, b: 2, c: 3] |> opts_predicate(fn {_k,v} -> v |> is_integer end)
{:ok, [a: 1, b: 2, c: 3]}
iex> [a: 1, b: 2, c: 3] |> opts_predicate(
...> fn
...> {:a,_} -> true
...> _ -> false
...> end)
{:error, %KeyError{key: [:b, :c], term: [a: 1, b: 2, c: 3]}}
iex> [a: 1, b: 2, c: 3] |> opts_predicate!(:not_a_function)
** (ArgumentError) expected valid tuple predicate; got: :not_a_function
iex> :not_opts |> opts_predicate!(&(&1))
** (ArgumentError) expected valid derivable opts; got: :not_opts
opts_reject/2
takes a derivable opts, together with a tuple predicate and returns {:ok, opts}
where opts
has all the 2tuples the tuple predicate returns false
for.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_reject(&(&1))
{:ok, []}
iex> [a: 1, b: 2, c: 3] |> opts_reject(
...> fn
...> {:a,_} -> true
...> _ -> false
...> end)
{:ok, [b: 2, c: 3]}
iex> %{a: 1, b: 2, c: 3} |> opts_reject(
...> fn
...> {:a,_} -> false
...> _ -> true
...> end)
{:ok, [a: 1]}
iex> {:error, error} = [a: 1, b: 2, c: 3] |> opts_reject(:not_a_function)
...> match?(%ArgumentError{message: "expected valid tuple predicate; got: :not_a_function"}, error)
true
iex> {:error, error} = :not_opts |> opts_reject(&(&1))
...> match?(%ArgumentError{message: "expected valid derivable opts; got: :not_opts"}, error)
true
opts_reject!(any(), any()) :: opts() | no_return()
opts_reject!/2
calls opts_reject/2
and if the result is {:ok, opts}
returns opts
.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_reject!(&(&1))
[]
iex> [a: 1, b: 2, c: 3] |> opts_reject!(
...> fn
...> {:a,_} -> true
...> _ -> false
...> end)
[b: 2, c: 3]
iex> %{a: 1, b: 2, c: 3} |> opts_reject!(
...> fn
...> {:a,_} -> false
...> _ -> true
...> end)
[a: 1]
iex> [a: 1, b: 2, c: 3] |> opts_reject!(:not_a_function)
** (ArgumentError) expected valid tuple predicate; got: :not_a_function
iex> :not_opts |> opts_reject!(&(&1))
** (ArgumentError) expected valid derivable opts; got: :not_opts
opts_reject_keys/2
takes a derivable opts and a key spec and returns {:ok, opts}
where opts
has all keys from the original derivable opts that do not appear in the key spec.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_reject_keys([:a, :b, :c])
{:ok, []}
iex> [a: 1, b: 2, c: 3] |> opts_reject_keys([b: "b value", c: :dont_want_this_key])
{:ok, [a: 1]}
iex> [a: 1, b: 2, c: 3] |> opts_reject_keys(%{a: nil, b: nil})
{:ok, [c: 3]}
iex> [a: 1, b: 2, c: 3] |> opts_reject_keys(:not_a_key_spec)
{:error, %ArgumentError{message: "expected enum; got: :not_a_key_spec"}}
iex> :not_opts |> opts_reject_keys([:a, :b, :c])
{:error, %ArgumentError{message: "expected valid derivable opts; got: :not_opts"}}
opts_reject_keys!(any(), any()) :: opts() | no_return()
opts_reject_keys!/2
calls opts_reject_keys/2
and if the result is {:ok, opts}
, returns opts
.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_reject_keys!([:a, :b, :c])
[]
iex> [a: 1, b: 2, c: 3] |> opts_reject_keys!([b: "b value", c: :dont_want_this_key])
[a: 1]
iex> [a: 1, b: 2, c: 3] |> opts_reject_keys!(%{a: nil, b: nil})
[c: 3]
iex> [a: 1, b: 2, c: 3] |> opts_reject_keys!(:not_a_key_spec)
** (ArgumentError) expected enum; got: :not_a_key_spec
iex> :not_opts |> opts_reject_keys!([:a, :b, :c])
** (ArgumentError) expected valid derivable opts; got: :not_opts
opts_sort_keys/
takes a derivable opts, together with a list of sort keys, and returns the opts sorted in the sort keys order. Duplicate keys follow one after another.
Any keys found but not given in the sort keys follow the sorted keys in the returned opts.
Any key in the sort list not found in the opts is ignored.
Examples
iex> [a: 1, b: 2, c: 3, d: 4] |> opts_sort_keys
[a: 1, b: 2, c: 3, d: 4]
iex> [a: 1, b: 2, c: 3, d: 4] |> opts_sort_keys([:c, :a])
[c: 3, a: 1, b: 2, d: 4]
iex> [] |> opts_sort_keys([:c, :a])
[]
iex> [a: 11, b: 2, c: 3, a: 12, d: 4] |> opts_sort_keys([:c, :a])
[c: 3, a: 11, a: 12, b: 2, d: 4]
iex> [a: 11, b: 21, c: 3, a: 12, d: 4, b: 22] |> opts_sort_keys([:d, :x, :b, :z])
[d: 4, b: 21, b: 22, a: 11, c: 3, a: 12]
See Keyword.take/2
.
opts_take_keys!/1
takes an opts, together with a key list and returns the opts with just the supplied keys.
It any of the keys are not found, raises a KeyError
citing the missing keys.
Examples
iex> [a: 1, b: 2, c: 3] |> opts_take_keys!([:c, :a])
[a: 1, c: 3]
iex> [a: 1, b: 2, c: 3] |> opts_take_keys!([:d, :a])
** (KeyError) key [:d] not found in: [a: 1, b: 2, c: 3]
opts_validate/1
returns {:ok, opts}
if the argument is an opts.
Any other argument causes {:error, error}
to be returned.
Examples
iex> [] |> opts_validate
{:ok, []}
iex> %{a: 1, b: 2, c: 3} |> opts_validate
{:error, %ArgumentError{message: "validate opts failed; got: %{a: 1, b: 2, c: 3}"}}
iex> %{"a" => 1, :b => 2, :c => 3} |> opts_validate
{:error, %ArgumentError{message: "validate opts failed; got: %{:b => 2, :c => 3, \"a\" => 1}"}}
iex> 42 |> opts_validate
{:error, %ArgumentError{message: "validate opts failed; got: 42"}}
iex> [a: nil, b: [:b1], c: [:c1, :c2, :c3]] |> opts_validate
{:ok, [a: nil, b: [:b1], c: [:c1, :c2, :c3]]}
opts_validate!/1
calls opts_validate/1
and, if the result is {:ok, opts}
, returns opts
.
Examples
iex> [] |> opts_validate!
[]
iex> %{a: 1, b: 2, c: 3} |> opts_validate!
** (ArgumentError) validate opts failed; got: %{a: 1, b: 2, c: 3}
iex> %{"a" => 1, :b => 2, :c => 3} |> opts_validate!
** (ArgumentError) validate opts failed; got: %{:b => 2, :c => 3, "a" => 1}
iex> 42 |> opts_validate!
** (ArgumentError) validate opts failed; got: 42
iex> [a: nil, b: [:b1], c: [:c1, :c2, :c3]] |> opts_validate!
[a: nil, b: [:b1], c: [:c1, :c2, :c3]]