Packages

A collection of extra utilities and extensions to the Elixir standard library

Current section

Files

Jump to
extra lib map extra.ex
Raw

lib/map/extra.ex

defmodule Map.Extra do
@moduledoc """
Extensions to the built-in `Map` module.
"""
@compile {:inline, assert_key!: 3}
@doc """
Raises an ArgumentError error if `map` does not have the provided `key`.
## Options
* `:message`: `binary`, the message to raise with when the value is missing.
* `:allow_nil_value`: `boolean`, Default: `true`. Set to true if a `nil` value
should not raise.
"""
@spec assert_key!(map, atom, keyword) :: :ok | no_return
def assert_key!(map, key, opts \\ []) do
message =
Keyword.get(opts, :message, "#{inspect(key)} is required to be in map.")
allow_nil_value? =
Keyword.get(opts, :allow_nil_value, true)
case Map.fetch(map, key) do
{:ok, nil} when not allow_nil_value? ->
raise(ArgumentError, message)
:error ->
raise(ArgumentError, message)
_ -> :ok
end
end
@doc """
Takes the fields specified by `keys` from `map` if their values are present and non `nil`.
## Examples
iex> Map.Extra.take_non_nil(%{name: nil}, [:name])
%{}
iex> Map.Extra.take_non_nil(%{name: "Jerome"}, [:name])
%{name: "Jerome"}
"""
@spec take_non_nil(map, list) :: map
def take_non_nil(map, keys) do
:lists.foldl(fn key, acc ->
case Map.get(map, key) do
nil -> acc
val -> Map.put(acc, key, val)
end
end, %{}, keys)
end
@doc """
Raises an ArgumentError if `map` does not have all of the provided `keys`.
## Options
* `:message`: `binary`, the message to raise with when the value is missing.
* `:allow_nil_value`: `boolean`, Default: `true`. Set to true if a `nil` value
should not raise.
"""
@spec assert_keys!(map, [key :: any], keyword) :: :ok | no_return
def assert_keys!(map, keys, opts \\ []) do
for key <- keys, do: assert_key!(map, key, opts)
:ok
end
@doc """
Returns `true` if the `map` has all of the `keys`.
"""
@spec has_keys?(map, Enum.t) :: boolean
def has_keys?(map, keys) do
keys |> Enum.all?(&Map.has_key?(map, &1))
end
end