Moar.Opts (Moar v4.3.0)

Copy Markdown View Source

Extracts keys and values from enumerables, especially from function options.

There are three main functions, each of which takes an opts enumerable as input. get/3 extracts one value from the opts with an optional default value. pop/3 is like get/3 but removes the opt from opts and returns the opt and the remaining opts as a tuple. take/2 extracts multiple values from the opts with optional default values for some or all keys.

get/3, pop/3, and take/2 differ from their Map and Keyword counterparts in the following ways:

  • get/3, pop/3, and take/2 accept any enumerable, including maps, keyword lists, and mixed lists like [:a, :b, c: 3, d: 4].
  • get/3, pop/3, and take/2 will fall back to the default value if the given key's value is blank as defined by Moar.Term.blank?/1 (nil, empty strings, strings made up only of whitespace, empty lists, and empty maps), and will default valueless keys (e.g., :a in [:a, b: 2]) to true unless a different default is specified. The corresponding Map and Keyword functions only fall back to the default value if the value is exactly nil, and Keyword functions don't support valueless keys.
  • get/3, pop/3, and take/2 allow default values to be specified.
  • take/2 will return the value for a requested key even if the key is not in the input enumerable.

Example using get/2 and get/3:

def build_url(path, opts \\ []) do
  %URI{
    path: path,
    host: Moar.Opts.get(opts, :host, "localhost"),
    port: Moar.Opts.get(opts, :port),
    scheme: "https"
  } |> URI.to_string()
end

Examples using take/2:

# example using pattern matching
def build_url(path, opts \ []) do
  %{host: h, port: p} = Moar.Opts.take(opts, [:port, host: "localhost"])
  %URI{path: path, host: h, port: p, scheme: "https"} |> URI.to_string()
end

# example rebinding `opts` to the parsed opts
def build_url(path, opts \ []) do
  opts = Moar.Opts.take(opts, [:port, host: "localhost"])
  %URI{path: path, host: opts.host, port: opts.port, scheme: "https"} |> URI.to_string()
end

Summary

Functions

Deletes an opt given a key, a {key, value}, or a function that accepts opts and a map, list, or term.

Get the value of key from input, falling back to optional default if the key does not exist, or if its value is blank (via Moar.Term.blank?/1).

Removes an opt from the opts (via get/3), returning {opt, remaining_opts}.

Get the value each key in keys from input, falling back to optional default values for keys that do not exist, or for values that are blank (via Moar.Term.blank?/1).

Functions

delete(input, fun)

@spec delete(map() | list(), any()) :: map() | list()

Deletes an opt given a key, a {key, value}, or a function that accepts opts and a map, list, or term.

iex> Moar.Opts.delete(%{a: 1, b: 2}, :a)
%{b: 2}

iex> Moar.Opts.delete([a: 1, b: 2], :a)
[b: 2]

iex> Moar.Opts.delete([:a, b: 2], :a)
[b: 2]

iex> Moar.Opts.delete([a: 1, b: 2], :a, 1)
[b: 2]

iex> Moar.Opts.delete([a: 1, b: 2], :a, 99)
[a: 1, b: 2]

iex> Moar.Opts.delete([:a, b: 2], :a, 1)
[:a, b: 2]

iex> Moar.Opts.delete([:trim, :downcase, :reverse], fn k -> k == :downcase end)
[:trim, :reverse]

iex> Moar.Opts.delete([a: 1, b: 2, c: 3, d: 4], fn {_k, v} -> Integer.mod(v, 2) == 0 end)
[a: 1, c: 3]

delete(input, key, value)

@spec delete(map() | list(), any(), any()) :: map() | list()

get(input, key, default \\ nil)

@spec get(Enum.t(), binary() | atom(), any()) :: any()

Get the value of key from input, falling back to optional default if the key does not exist, or if its value is blank (via Moar.Term.blank?/1).

iex> [a: 1, b: 2] |> Moar.Opts.get(:a)
1

iex> [:a, b: 2] |> Moar.Opts.get(:a)
true

iex> [a: 1, b: 2] |> Moar.Opts.get(:c)
nil

iex> [a: 1, b: 2, c: ""] |> Moar.Opts.get(:c)
nil

iex> [a: 1, b: 2, c: %{}] |> Moar.Opts.get(:c)
nil

iex> [a: 1, b: 2, c: "   "] |> Moar.Opts.get(:c, 300)
300

pop(input, key, default \\ nil)

@spec pop(Enum.t(), binary() | atom(), any()) :: {any(), Enum.t()}

Removes an opt from the opts (via get/3), returning {opt, remaining_opts}.

iex> [a: 1, b: 2] |> Moar.Opts.pop(:a)
{1, [b: 2]}

iex> [:a, b: 2] |> Moar.Opts.pop(:a)
{true, [b: 2]}

replace(opts, key, replacement)

@spec replace(map(), {any(), any()}, {any(), any()}) :: map()
@spec replace(list(), {any(), any()} | any(), any()) :: list()

Replace an opt.

iex> Moar.Opts.replace(%{a: 1, b: 2}, {:a, 1}, {:a, 100})
%{a: 100, b: 2}

iex> Moar.Opts.replace([a: 1, b: 2], {:a, 1}, {:a, 100})
[a: 100, b: 2]

iex> Moar.Opts.replace([:a, b: 2], :a, :aa)
[:aa, b: 2]

take(input, keys)

@spec take(Enum.t(), list()) :: map()

Get the value each key in keys from input, falling back to optional default values for keys that do not exist, or for values that are blank (via Moar.Term.blank?/1).

If key does not exist in keys, returns nil, or returns the default value if provided.

keys is a list of keys (e.g., [:a, :b]), a keyword list of keys and default values (e.g., [a: 1, b: 2]), or a hybrid list/keyword list (e.g., [:a, b: 2])

iex> [a: 1, b: 2] |> Moar.Opts.take([:a, :c])
%{a: 1, c: nil}

iex> [:a, b: 2] |> Moar.Opts.take([:a, :c])
%{a: true, c: nil}

iex> [a: 1, b: 2] |> Moar.Opts.take([:a, b: 0, c: 3])
%{a: 1, b: 2, c: 3}