Packages

Defining non trivial transformations from incoming maps to Structs.

Current section

Files

Jump to
exmapper lib ex_mapper def_mapping.ex
Raw

lib/ex_mapper/def_mapping.ex

defmodule ExMapper.DefMapping do
defmacro __using__(_) do
quote do
require ExMapper.DefMapping
import ExMapper.DefMapping
@before_compile { unquote(__MODULE__), :__before_compile__ }
@mappings %ExMapper.Options{}
def many(struct, opts \\ %ExMapper.Options{}), do: &many(struct, &1, opts)
defp many(struct, value, opts) when is_list(value), do: value |> Enum.map(&one(struct, &1, opts))
defp many(_, _, _), do: []
def one(struct, opts \\ %ExMapper.Options{}), do: &one(struct, &1, opts)
defp one(struct, val, opts), do: ExMapper.map(struct, val, opts)
end
end
defmacro __before_compile__(_) do
quote do
def mappings(), do: @mappings
end
end
defmacro defmapping(block) do
quote do
unquote(block)
end
end
defmacro keys(val) do
func_name = "keys_func" |> String.to_atom
use_value_default = is_atom(val)
quote do
if(!unquote(use_value_default)) do
localize_function(unquote(func_name), unquote(val))
end
@mappings Map.put(@mappings, :keys,
if(unquote(use_value_default), do: unquote(val), else: &__MODULE__.unquote(func_name)/1)
)
end
end
defmacro override(struct_key, override) do
key = Keyword.get(override, :key, :default)
value = Keyword.get(override, :value, :default)
key_func_name = "#{struct_key}_key" |> String.to_atom
value_func_name = "#{struct_key}_value" |> String.to_atom
# Note: Akward that we must do this here, but we cannot evaluate the value of key/value in quote incase its a missing local function
use_key_default = key == :default
use_value_default = value == :default
quote do
localize_function(unquote(key_func_name), unquote(key))
localize_function(unquote(value_func_name), unquote(value))
overrides = Map.put(Map.get(@mappings, :overrides), unquote(struct_key), %ExMapper.Override{
key: if(unquote(use_key_default), do: :default, else: &__MODULE__.unquote(key_func_name)/1),
value: if(unquote(use_value_default), do: :default, else: &__MODULE__.unquote(value_func_name)/1)
})
@mappings Map.put(@mappings, :overrides, overrides)
end
end
defmacro localize_function(name, defenition) do
if(is_tuple(defenition)) do
quote do
def unquote(name)(input), do: unquote(defenition).(input)
end
else
quote do
def unquote(name)(input), do: unquote(defenition)
end
end
end
end