defmodule Braintree.Util do
@moduledoc """
General purpose utility functions.
"""
@doc """
Converts hyphenated values to underscore delimited strings.
## Examples
iex> Braintree.Util.underscorize("brain-tree")
"brain_tree"
iex> Braintree.Util.underscorize(:"brain-tree")
"brain_tree"
"""
@spec underscorize(String.t() | atom) :: String.t()
def underscorize(value) when is_atom(value), do: underscorize(Atom.to_string(value))
def underscorize(value) when is_binary(value), do: String.replace(value, "-", "_")
@doc """
Converts underscored values to hyphenated strings.
## Examples
iex> Braintree.Util.hyphenate("brain_tree")
"brain-tree"
iex> Braintree.Util.hyphenate(:brain_tree)
"brain-tree"
"""
@spec hyphenate(String.t() | atom) :: String.t()
def hyphenate(value) when is_atom(value), do: value |> to_string() |> hyphenate()
def hyphenate(value) when is_binary(value), do: String.replace(value, "_", "-")
@doc """
Recursively convert a map of string keys into a map with atom keys. Intended
to prepare responses for conversion into structs. Note that it converts any
string into an atom, whether it existed or not.
For unknown maps with unknown keys this is potentially dangerous, but should
be fine when used with known Braintree endpoints.
## Example
iex> Braintree.Util.atomize(%{"a" => 1, "b" => %{"c" => 2}})
%{a: 1, b: %{c: 2}}
iex> Braintree.Util.atomize(%{a: 1, b: %{"c" => 2}})
%{a: 1, b: %{c: 2}}
"""
@spec atomize(map) :: map
def atomize(map) when is_map(map) do
Enum.into(map, %{}, fn
{key, val} when is_atom(key) and is_map(val) -> {key, atomize(val)}
{key, val} when is_atom(key) -> {key, val}
{key, val} when is_map(val) -> {String.to_atom(key), atomize(val)}
{key, val} -> {String.to_atom(key), val}
end)
end
end