Current section

Files

Jump to
amoc src config amoc_config_utils.erl
Raw

src/config/amoc_config_utils.erl

%% @private
%% @see amoc_config
%% @copyright 2023 Erlang Solutions Ltd.
-module(amoc_config_utils).
-include("amoc_config.hrl").
%% API
-export([maybe_error/2,
pipeline/2,
merge_config/2,
override_config/2,
store_scenario_config/1,
create_amoc_config_ets/0]).
-spec maybe_error(error_type(), [{error, reason()} | {ok, any()}]) ->
error() | {ok, [any()]}.
maybe_error(ErrorType, List) ->
case [Reason || {error, Reason} <- List] of
[] ->
{ok, [CorrectValue || {ok, CorrectValue} <- List]};
Errors ->
{error, ErrorType, Errors}
end.
-spec pipeline([{function(), Args :: [any()]}], any()) -> any().
pipeline(Actions, InitValue) ->
lists:foldl(fun run_action/2, InitValue, Actions).
run_action({Fun, Args}, {ok, FirstArg}) ->
try_apply_fn(Fun, [FirstArg | Args]);
run_action({Fun, Args}, ok) ->
try_apply_fn(Fun, Args);
run_action(_, Error) -> Error.
try_apply_fn(Fun, Args) ->
try
apply(Fun, Args)
catch
C:E:S -> {error, pipeline_action_crashed, {C, E, S}}
end.
-spec merge_config(module_configuration(), module_configuration()) ->
maybe_module_config().
merge_config(MergedConfig, []) ->
{ok, MergedConfig};
merge_config(OldConfig, [#module_parameter{name = Name, mod = Module} = Param | L]) ->
case lists:keyfind(Name, #module_parameter.name, OldConfig) of
false ->
merge_config([Param | OldConfig], L);
#module_parameter{name = Name, mod = AnotherModule} ->
{error, parameter_overriding, {Name, Module, AnotherModule}}
end.
-spec override_config(module_configuration(), module_configuration()) ->
{ok, module_configuration()}.
override_config(OldConfig, NewConfig) ->
ReversedNewConfig = lists:reverse(NewConfig),
FullConfig = ReversedNewConfig ++ OldConfig,
{ok, lists:ukeysort(#module_parameter.name, FullConfig)}.
-spec store_scenario_config(module_configuration()) -> ok.
store_scenario_config(Config) ->
true = ets:insert(amoc_config, Config),
ok.
-spec create_amoc_config_ets() -> any().
create_amoc_config_ets() ->
amoc_config = ets:new(amoc_config, [named_table,
protected,
{keypos, #module_parameter.name},
{read_concurrency, true}]).