Skip to content

Commit

Permalink
Allow config processor to be a list of functions
Browse files Browse the repository at this point in the history
This way, you can specify a list instead of having to merge functions

Also: remove the 'list_processor' type, because it was created when all
sections would be formatted as lists. Now they are formatted as maps
by default. What's more, if sections are merged, only the first
processor gets a map/list as the argument, and it can pass anything to
the subsequent processors.

The 'processor' type covers all such cases.
  • Loading branch information
chrzaszcz committed Nov 13, 2024
1 parent b6e8e2f commit 0a8cd55
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 23 deletions.
6 changes: 3 additions & 3 deletions include/mongoose_config_spec.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
required = [] :: [mongoose_config_parser_toml:toml_key()] | all,
validate = any :: mongoose_config_validator:section_validator(),
format_items = map :: mongoose_config_spec:format_items(),
process :: undefined | mongoose_config_parser_toml:list_processor(),
process = [] :: mongoose_config_parser_toml:processor(),
defaults = #{} :: #{mongoose_config_parser_toml:toml_key() =>
mongoose_config_parser_toml:config_part()},
wrap = default :: mongoose_config_spec:wrapper(),
Expand All @@ -16,12 +16,12 @@
-record(list, {items :: mongoose_config_spec:config_node(),
validate = any :: mongoose_config_validator:list_validator(),
format_items = list :: mongoose_config_spec:format_items(),
process :: undefined | mongoose_config_parser_toml:list_processor(),
process = [] :: mongoose_config_parser_toml:processor(),
wrap = default :: mongoose_config_spec:wrapper()}).

-record(option, {type :: mongoose_config_spec:option_type(),
validate = any :: mongoose_config_validator:validator(),
process :: undefined | mongoose_config_parser_toml:processor(),
process = [] :: mongoose_config_parser_toml:processor(),
wrap = default :: mongoose_config_spec:wrapper()}).

-endif.
22 changes: 9 additions & 13 deletions src/config/mongoose_config_parser_toml.erl
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@

-export([parse_file/1]).

%% Utilities for section manipulation
-export([process/3]).

-ifdef(TEST).
-export([process/1,
extract_errors/1]).
Expand All @@ -27,11 +24,9 @@
-type config_error() :: #{class := error, what := atom(), text := string(), any() => any()}.
-type config() :: top_level_config() | config_error().

-type list_processor() :: fun((path(), [config_part()]) -> config_part())
| fun(([config_part()]) -> config_part()).

-type processor() :: fun((path(), config_part()) -> config_part())
| fun((config_part()) -> config_part()).
-type processor() :: processor_fun() | [processor_fun()].
-type processor_fun() :: fun((path(), config_part()) -> config_part())
| fun((config_part()) -> config_part()).

-type step() ::
parse % Recursive processing (section/list) or type conversion (leaf option)
Expand All @@ -54,7 +49,7 @@

-export_type([toml_key/0, toml_value/0, toml_section/0,
option_value/0, config/0, config_error/0, config_part/0,
list_processor/0, processor/0, path/0]).
processor/0, path/0]).

-spec parse_file(FileName :: string()) -> mongoose_config_parser:state().
parse_file(FileName) ->
Expand Down Expand Up @@ -205,14 +200,15 @@ validate(Value, #option{type = Type, validate = Validator}) ->
mongoose_config_validator:validate(Value, Type, Validator).

-spec process_spec(mongoose_config_spec:config_section() |
mongoose_config_spec:config_list()) -> undefined | list_processor();
(mongoose_config_spec:config_option()) -> undefined | processor().
mongoose_config_spec:config_list() |
mongoose_config_spec:config_option()) -> processor().
process_spec(#section{process = Process}) -> Process;
process_spec(#list{process = Process}) -> Process;
process_spec(#option{process = Process}) -> Process.

-spec process(path(), config_part(), undefined | processor()) -> config_part().
process(_Path, V, undefined) -> V;
-spec process(path(), config_part(), processor()) -> config_part().
process(Path, V, Functions) when is_list(Functions) ->
lists:foldl(fun(F, Value) -> process(Path, Value, F) end, V, Functions);
process(_Path, V, F) when is_function(F, 1) -> F(V);
process(Path, V, F) when is_function(F, 2) -> F(Path, V).

Expand Down
8 changes: 1 addition & 7 deletions src/config/mongoose_config_utils.erl
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,4 @@ merge_sections(BasicSection, ExtraSection) ->
BasicSection#section{items = maps:merge(Items1, Items2),
required = Required1 ++ Required2,
defaults = maps:merge(Defaults1, Defaults2),
process = merge_process_functions(Process1, Process2)}.

merge_process_functions(Process1, Process2) ->
fun(Path, V) ->
V1 = mongoose_config_parser_toml:process(Path, V, Process1),
mongoose_config_parser_toml:process(Path, V1, Process2)
end.
process = lists:flatten([Process1, Process2])}.

0 comments on commit 0a8cd55

Please sign in to comment.