|
| 1 | +%%%------------------------------------------------------------------- |
| 2 | +%%% @author denys |
| 3 | +%%% @copyright (C) 2019, <COMPANY> |
| 4 | +%%% @doc |
| 5 | +%%% |
| 6 | +%%% @end |
| 7 | +%%% Created : 30. Mar 2019 01:15 |
| 8 | +%%%------------------------------------------------------------------- |
| 9 | +-module(config). |
| 10 | +-author("denys"). |
| 11 | + |
| 12 | +%% API |
| 13 | +-export([get_scenario_settings/1, store_scenario_settings/1, get_parameter/1, dump_settings/0]). |
| 14 | + |
| 15 | +-export_type([scenario_configuration/0, settings/0]). |
| 16 | + |
| 17 | +-type name() :: atom(). |
| 18 | +-type env_var() :: atom(). |
| 19 | +-type value() :: any(). |
| 20 | + |
| 21 | +-type one_of() :: [any()]. |
| 22 | +-type func() :: fun((any()) -> boolean()). |
| 23 | +-type validation() :: func() | one_of() | bitstring | nonnegative_integer | positive_integer | none. |
| 24 | +-type reason() :: atom(). |
| 25 | + |
| 26 | +-type parameter_configuration() :: {name(), env_var(), DefValue :: value(), validation()}. |
| 27 | +-type scenario_configuration() :: [parameter_configuration()]. |
| 28 | + |
| 29 | +-type settings() :: [{name(), value()}]. |
| 30 | +-type invalid_settings() :: {invalid_settings, [{name(), value(), reason()}]}. |
| 31 | + |
| 32 | +-spec get_scenario_settings(scenario_configuration()) -> {ok, settings()} | {error, invalid_settings()}. |
| 33 | +get_scenario_settings(Config) -> |
| 34 | + ParametersVerification = [get_value_and_verify(C) || C <- Config], |
| 35 | + case [{N, V, R} || {N, V, {false, R}} <- ParametersVerification] of |
| 36 | + [] -> {ok, [{Name, Value} || {Name, Value, _} <- ParametersVerification]}; |
| 37 | + InvalidSettings -> {error, {invalid_settings, InvalidSettings}} |
| 38 | + end. |
| 39 | + |
| 40 | +-spec store_scenario_settings(settings()) -> any(). |
| 41 | +store_scenario_settings(Settings) -> |
| 42 | + erlang:put(scenario_settings, Settings). |
| 43 | + |
| 44 | +-spec get_parameter(name()) -> {ok, value()} | {error, no_settings | no_parameter}. |
| 45 | +get_parameter(Name) -> |
| 46 | + case erlang:get(scenario_settings) of |
| 47 | + undefined -> {error, no_settings}; |
| 48 | + Settings -> |
| 49 | + case lists:keyfind(Name, 1, Settings) of |
| 50 | + false -> {error, no_parameter}; |
| 51 | + {Name, Value} -> {ok, Value} |
| 52 | + end |
| 53 | + end. |
| 54 | + |
| 55 | +-spec dump_settings() -> any(). |
| 56 | +dump_settings() -> |
| 57 | + case erlang:get(scenario_settings) of |
| 58 | + undefined -> lager:error("no scenario settings"); |
| 59 | + Settings -> lager:info("scenario settings: ~p", [Settings]) |
| 60 | + end. |
| 61 | + |
| 62 | +get_value_and_verify({Name, Env, DefaultValue, VerificationMethod}) -> |
| 63 | + Value = amoc_config:get(Env, DefaultValue), |
| 64 | + DefaultValueVerification = verify_value(DefaultValue, VerificationMethod), |
| 65 | + ValueVerification = verify_value(Value, VerificationMethod), |
| 66 | + Verification = case {DefaultValueVerification, ValueVerification} of |
| 67 | + {true, true} -> true; |
| 68 | + {true, false} -> |
| 69 | + lager:error("Invalid default value for ~p", [Name]), |
| 70 | + {false, bad_default_value}; |
| 71 | + {false, true} -> |
| 72 | + lager:error("Invalid value for ~p", [Name]), |
| 73 | + {false, bad_value}; |
| 74 | + {false, false} -> |
| 75 | + lager:error("Invalid default value & value for ~p", [Name]), |
| 76 | + {false, bad_value_bad_default_value} |
| 77 | + end, |
| 78 | + {Name, Value, Verification}. |
| 79 | + |
| 80 | +verify_value(_, none) -> true; |
| 81 | +verify_value(Value, positive_integer) -> |
| 82 | + is_positive_integer(Value); |
| 83 | +verify_value(Value, nonnegative_integer) -> |
| 84 | + is_nonnegative_integer(Value); |
| 85 | +verify_value(Value, bitstring) -> |
| 86 | + is_bitstring(Value); |
| 87 | +verify_value(Value, [_ | _] = NonemptyList) -> |
| 88 | + is_one_of(Value, NonemptyList); |
| 89 | +verify_value(Value, Fun) when is_function(Fun, 1) -> |
| 90 | + Fun(Value); |
| 91 | +verify_value(_, VerificationMethod) -> |
| 92 | + lager:error("invalid verification method ~p", [VerificationMethod]), |
| 93 | + false. |
| 94 | + |
| 95 | +is_positive_integer(I) -> is_integer(I) andalso I > 0. |
| 96 | + |
| 97 | +is_nonnegative_integer(I) -> is_integer(I) andalso I >= 0. |
| 98 | + |
| 99 | +is_one_of(Element, List) -> lists:any(fun(El) -> El =:= Element end, List). |
| 100 | + |
0 commit comments