/
config_macros.ex
85 lines (67 loc) · 2.27 KB
/
config_macros.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
defmodule Versioce.Config.Macros do
@moduledoc false
@doc """
Macro to define a simple config value or by path.
`path` is a list of atoms with `key` at the end, ex:
[:level1, :level2, :key]
`key`s should be unique for their module.
When called, value will either be picked from Application or default.
ex.:
value :foo, "default value", "description"
value [:spam, :eggs], %{}, "another description"
"""
defmacro value(key_or_path, default, doc \\ "")
defmacro value(key, default, doc) when is_atom(key) do
quote do
@doc """
Get config value for #{to_string(unquote(key))}
#{unquote(doc)}
You can configure it with:
config :versioce,
#{to_string(unquote(key))}: #{inspect(unquote(default))}
Value for this configuration should either be a literal value or a function
of 0 arity, that will return the value, ex:
config :versioce,
#{to_string(unquote(key))}: fn -> #{inspect(unquote(default))} end
"""
def unquote(key)() do
with {:ok, val} <- Application.fetch_env(:versioce, unquote(key)) do
cond do
is_function(val, 0) -> apply(val, [])
true -> val
end
else
_ -> unquote(default)
end
end
end
end
defmacro value(path, default, doc) when is_list(path) do
h = List.first(path)
t = List.last(path)
quote do
@doc """
Get config value for #{to_string(unquote(t))}
#{unquote(doc)}
You can configure it with:
config :versioce, #{inspect(unquote(h))},
#{to_string(unquote(t))}: #{inspect(unquote(default))}
Value for this configuration should either be a literal value or a function
of 0 arity, that will return the value, ex:
config :versioce, #{inspect(unquote(h))},
#{to_string(unquote(t))}: fn -> #{inspect(unquote(default))} end
"""
def unquote(t)() do
with {:ok, val} <- Application.fetch_env(:versioce, unquote(h)),
{:ok, val} <- Keyword.fetch(val, unquote(t)) do
cond do
is_function(val, 0) -> apply(val, [])
true -> val
end
else
_ -> unquote(default)
end
end
end
end
end