Current section
Files
Jump to
Current section
Files
lib/key_tools.ex
defmodule KeyTools do
@moduledoc """
Provides common functions for coercing a `Map` or `List`.
"""
@doc """
Deeply converts all string keys within the given `Map` or `List` to atoms.
## Examples
iex(1)> KeyTools.atomize_keys %{"data" => ["Hello", "World!"]}
%{data: ["Hello", "World!"]}
iex(2)> KeyTools.atomize_keys [%{"nested_data" => %{"deep" => :stuff}}]
[%{nested_data: %{deep: :stuff}}]
"""
def atomize_keys(map) when is_map(map) do
for {key, value} <- map, into: %{}, do: {String.to_atom(key), atomize_keys(value)}
end
def atomize_keys(list) when is_list(list), do: Enum.map list, &atomize_keys/1
def atomize_keys(anything), do: anything
@doc """
Deeply converts all camelCased keys within the given `Map` or `List` to snake_case.
Affects only keys; values will remain unchanged. Works on string and atom keys.
The same limitations detailed in the docs for `Macro.Underscore` apply here,
so be careful if there is potential for non-standard within your keys.
## Examples
iex(1)> KeyTools.underscore_keys %{"scumbagKey" => "is a camel"}
%{"scumbag_key" => "is a camel"}
iex(2)> KeyTools.underscore_keys [%{"nestedKeys" => %{"greatSuccess" => ":)"}}]
[%{"nested_keys" => %{"great_success" => ":)"}}]
"""
def underscore_keys(map) when is_map(map) do
for {key, value} <- map, into: %{} do
if is_binary(key) do
{Macro.underscore(key), underscore_keys(value)}
else
{underscore_keys(key), underscore_keys(value)}
end
end
end
def underscore_keys(list) when is_list(list) do
Enum.map list, &underscore_keys/1
end
def underscore_keys(atom) when is_atom(atom) do
atom
|> Atom.to_string
|> Macro.underscore
|> String.to_atom
end
def underscore_keys(anything), do: anything
@doc """
Deeply converts all keys within the given `Map` or `List` to strings.
## Examples
iex(1)> stringify_keys %{atom_key: :atom_value}
%{"atom_key" => :atom_value}
iex(2)> stringify_keys [%{atom_key: %{42 => [%{another_key: 23}]}}]
[%{"atom_key" => %{"42" => [%{"another_key" => 23}]}}]
"""
def stringify_keys(map) when is_map(map) do
for {key, value} <- map, into: %{}, do: {to_string(key), stringify_keys(value)}
end
def stringify_keys(list) when is_list(list), do: Enum.map list, &stringify_keys/1
def stringify_keys(anything), do: anything
end