Current section
Files
Jump to
Current section
Files
lib/util.ex
defmodule Pointers.Util do
@moduledoc false
@bad_source "You must provide a binary :source option."
@bad_otp_app "You must provide a valid atom :otp_app option."
# maps a tuple flip over a list
def flip(list) when is_list(list),
do: Enum.map(list, fn {k, v} -> {v, k} end)
def add_binaries(list) when is_list(list) do
Enum.flat_map(list, fn {k, v} when is_atom(k) and is_atom(v) ->
[{k, v}, {Atom.to_string(k), Atom.to_string(v)}]
end)
end
# renames keys in a map or keyword list
def rename(map, changes) when is_map(map) do
Enum.reduce(changes, map, fn {k, l}, map ->
case map do
%{^k => v} -> Map.put(Map.delete(map, k), l, v)
_ -> map
end
end)
end
def rename(kw, changes) when is_list(kw) do
Enum.reduce(changes, kw, fn {k, l}, kw ->
case Keyword.fetch(kw, k) do
{:ok, v} -> [{l, v} | Keyword.delete(kw, k)]
_ -> kw
end
end)
end
# option processing
def get_source(opts), do: check_source(Keyword.get(opts, :source))
defp check_source(x) when is_binary(x), do: x
defp check_source(_), do: raise ArgumentError, message: @bad_source
def get_otp_app(opts), do: check_otp_app(Keyword.get(opts, :otp_app))
defp check_otp_app(x) when is_atom(x), do: x
defp check_otp_app(_), do: raise ArgumentError, message: @bad_otp_app
# expands to putting the attribute if it does not already exist
def put_new_attribute(module, attribute, value) do
if not Module.has_attribute?(module, attribute) do
quote do
Module.put_attribute(unquote(module), unquote(attribute), unquote(value))
end
end
end
# defaults the foreign key type to ULID
def schema_foreign_key_type(module),
do: put_new_attribute(module, :foreign_key_type, Pointers.ULID)
def pointers_clause(arg, value) do
quote do
def __pointers__(unquote(arg)), do: unquote(value)
end
end
end