Current section
Files
Jump to
Current section
Files
lib/weave.ex
defmodule Weave do
@moduledoc """
Weave
"""
defmacro __using__(_opts) do
quote do
import Weave
@required []
@configured []
@spec configure(only: list, loaders: list) :: :ok
@before_compile Weave
end
end
defmacro weave(name, required: true, handler: handler) do
quote do
@required [unquote(name)] ++ @required
generate_handler(unquote(name), unquote(handler))
end
end
defmacro weave(name, required: false, handler: handler) do
quote do
generate_handler(unquote(name), unquote(handler))
end
end
defmacro weave(name, handler: handler) do
quote do
generate_handler(unquote(name), unquote(handler))
end
end
defmacro generate_handler(name, handler = {:fn, _, _}) when is_tuple(handler) do
quote do
def handle_configuration(unquote(name), value) do
unquote(handler).(value)
end
end
end
defmacro generate_handler(name, handler) when is_tuple(handler) do
quote do
def handle_configuration(unquote(name), value) do
{app, key} = unquote(handler)
{app, key, value}
end
end
end
defmacro generate_handler(name, handler) when is_list(handler) do
quote do
def handle_configuration(unquote(name), value) do
Enum.map(unquote(handler), fn {app, key} ->
{app, key, value}
end)
end
end
end
defmacro __before_compile__(_environment) do
quote do
def configure(config) do
only = Keyword.get(config, :only, nil)
config
|> Keyword.get(:loaders, [])
|> Enum.map(fn {loader, options} ->
loader.load_configuration(
options: options,
only: only,
handler: __MODULE__
)
end)
|> strict()
:ok
end
def strict(configured_keys) do
missing_keys = @required -- List.flatten(configured_keys)
if Kernel.length(missing_keys) > 0 do
raise "Not all required configuration met. Missing #{inspect(missing_keys)}"
end
end
end
end
end