Current section
Files
Jump to
Current section
Files
lib/util.ex
defmodule ExKeyCDN.Util do
@moduledoc """
General purpose utility functions.
"""
@doc """
Converts hyphenated values to underscore delimited strings.
## Examples
iex> ExKeyCDN.Util.underscorize("key-cdn")
"key_cdn"
iex> ExKeyCDN.Util.underscorize(:"key-cdn")
"key_cdn"
"""
@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> ExKeyCDN.Util.hyphenate("key_cdn")
"key-cdn"
iex> ExKeyCDN.Util.hyphenate(:key_cdn)
"key-cdn"
"""
@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 ExKeyCDN endpoints.
## Example
iex> ExKeyCDN.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_map(val) -> {String.to_atom(key), atomize(val)}
{key, val} -> {String.to_atom(key), val}
end)
end
@spec successfull?(map) ::
{false, binary()} | {true, map}
def successfull?(%{"status" => status, "description" => description} = result) do
if status == "success" do
{true, result}
else
{false, description}
end
end
def successfull?(_result),
do: {false, "API changed, :ok resopnse body does not contain status and description keys."}
@spec map_to_struct(
list,
ExKeyCDN.Zone
| ExKeyCDN.ZoneAlias
| ExKeyCDN.ZoneReferrer
| ExKeyCDN.Statistic
| ExKeyCDN.StatusStatistic
| ExKeyCDN.CreditStatistic,
binary
) ::
list | map
def map_to_struct([], _type, _key), do: []
def map_to_struct(items, type, key) do
values = data(items, key)
cond do
is_nil(values) -> {:error, "API changed or data key value did not sent."}
is_map(values) -> struct(type, map_to_keywordlist(values))
true -> Enum.map(values, fn item -> struct(type, map_to_keywordlist(item)) end)
end
end
defp data(items, key), do: items[key]
@spec map_to_keywordlist(map) :: list(keyword)
def map_to_keywordlist(map) when is_map(map),
do: Enum.map(map, fn {key, value} -> {String.to_atom(key), value} end)
def map_to_keywordlist(_map) do
raise ArgumentError, message: "not a map in response list"
end
@spec get_limits(list(keyword)) :: [{:rate_limit, binary}, {:rate_limit_remaining, binary}]
def get_limits(headers) do
rate_limit = List.keyfind(headers, "X-Rate-Limit-Limit", 0)
rate_limit = if rate_limit, do: elem(rate_limit, 1), else: :not_sent
rate_limit_remaining = List.keyfind(headers, "X-Rate-Limit-Remaining", 0)
rate_limit_remaining =
if rate_limit_remaining, do: elem(rate_limit_remaining, 1), else: :not_sent
Keyword.put([], :rate_limit, rate_limit)
|> Keyword.put(:rate_limit_remaining, rate_limit_remaining)
end
@spec http :: ExKeyCDN.HTTP
def http do
Application.get_env(:exkeycdn, :http)
end
end