./ct_report/coverage/mongoose_config.COVER.html

1 -module(mongoose_config).
2
3 %% API
4 -export([start/0,
5 stop/0,
6 get_config_path/0,
7 lookup_opt/1,
8 get_opt/2,
9 get_opt/1]).
10
11 %% Test API, do not use outside of test suites
12 -export([set_opts/1,
13 get_opts/0,
14 erase_opts/0,
15 set_opt/2,
16 unset_opt/1]).
17
18 -ignore_xref([set_opts/1, get_opts/0, erase_opts/0, set_opt/2, unset_opt/1]).
19
20 -include("mongoose.hrl").
21
22 -type key() :: atom() | host_type_key().
23 -type host_type_key() :: {atom(), mongooseim:host_type_or_global()}.
24
25 %% Top-level key() followed by inner_key() for each of the nested maps
26 -type key_path() :: [key() | inner_key()].
27 -type inner_key() :: atom() | binary() | integer() | string() | tuple().
28
29 -type value() :: atom() | binary() | integer() | string() | [value()] | tuple() | map().
30
31 -export_type([host_type_key/0, key/0, key_path/0, value/0]).
32
33 -spec start() -> ok.
34 start() ->
35 104 Path = get_config_path(),
36 104 Opts = mongoose_config_parser:parse_file(Path),
37 104 set_opts(maps:from_list(Opts)).
38
39 -spec stop() -> ok | {error, not_started}.
40 stop() ->
41 104 case erase_opts() of
42 true ->
43 104 ok;
44 false ->
45
:-(
{error, not_started}
46 end.
47
48 %% @doc Get the filename of the ejabberd configuration file.
49 %% The filename can be specified with: erl -config "/path/to/mongooseim.toml".
50 %% It can also be specified with the environment variable EJABBERD_CONFIG_PATH.
51 %% If not specified, the default value 'mongooseim.toml' is assumed.
52 -spec get_config_path() -> string().
53 get_config_path() ->
54 147 DefaultPath = case os:getenv("EJABBERD_CONFIG_PATH") of
55
:-(
false -> ?CONFIG_PATH;
56 147 Path -> Path
57 end,
58 147 application:get_env(mongooseim, config, DefaultPath).
59
60 -spec set_opts(#{key() => value()}) -> ok.
61 set_opts(Opts) ->
62 104 persistent_term:put(?MODULE, Opts).
63
64 -spec get_opts() -> #{key() => value()}.
65 get_opts() ->
66
:-(
persistent_term:get(?MODULE).
67
68 -spec erase_opts() -> boolean().
69 erase_opts() ->
70 104 persistent_term:erase(?MODULE).
71
72 -spec set_opt(key() | key_path(), value()) -> ok.
73 set_opt(KeyPath, Value) when is_list(KeyPath) ->
74 3870 Opts = persistent_term:get(?MODULE),
75 3870 NewOpts = set_nested_opt(Opts, KeyPath, Value),
76 3870 persistent_term:put(?MODULE, NewOpts);
77 set_opt(Key, Value) ->
78 3811 set_opt([Key], Value).
79
80 -spec unset_opt(key() | key_path()) -> ok.
81 unset_opt(KeyPath) when is_list(KeyPath) ->
82 27 Opts = persistent_term:get(?MODULE),
83 27 NewOpts = unset_nested_opt(Opts, KeyPath),
84 27 persistent_term:put(?MODULE, NewOpts);
85 unset_opt(Key) ->
86 26 unset_opt([Key]).
87
88 %% @doc Use instead of get_opt(Key, undefined)
89 -spec lookup_opt(key() | key_path()) -> {ok, value()} | {error, not_found}.
90 lookup_opt(Key) ->
91 52724 try get_opt(Key) of
92 26380 Value -> {ok, Value}
93 catch
94 26344 error:{badkey, _} -> {error, not_found} % missing map key
95 end.
96
97 % @doc Returns Default if the option does not exist
98 -spec get_opt(key() | key_path(), value()) -> value().
99 get_opt(Key, Default) ->
100 79210 try
101 79210 get_opt(Key)
102 catch
103 37356 error:{badkey, _} -> Default % missing map key
104 end.
105
106 %% @doc Fails if the option does not exist
107 -spec get_opt(key() | key_path()) -> value().
108 get_opt(KeyPath) when is_list(KeyPath) ->
109 2205144 Opts = persistent_term:get(?MODULE),
110 2205144 lists:foldl(fun maps:get/2, Opts, KeyPath);
111 get_opt(Key) ->
112 1561395 get_opt([Key]).
113
114 %% Internal functions
115
116 set_nested_opt(M, [Key], Value) ->
117 3870 M#{Key => Value};
118 set_nested_opt(M, [Key | Path], Value) ->
119 29 M#{Key => set_nested_opt(maps:get(Key, M), Path, Value)}.
120
121 unset_nested_opt(M, [Key]) ->
122 27 maps:remove(Key, M);
123 unset_nested_opt(M, [Key | Path]) ->
124 1 M#{Key := unset_nested_opt(maps:get(Key, M), Path)}.
Line Hits Source