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