From 0a8cd5580399ac1d04c24b704861108ad9730f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chrz=C4=85szcz?= Date: Wed, 13 Nov 2024 14:08:09 +0100 Subject: [PATCH] Allow config processor to be a list of functions 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. --- include/mongoose_config_spec.hrl | 6 +++--- src/config/mongoose_config_parser_toml.erl | 22 +++++++++------------- src/config/mongoose_config_utils.erl | 8 +------- 3 files changed, 13 insertions(+), 23 deletions(-) diff --git a/include/mongoose_config_spec.hrl b/include/mongoose_config_spec.hrl index c5ca296a353..6e707f83348 100644 --- a/include/mongoose_config_spec.hrl +++ b/include/mongoose_config_spec.hrl @@ -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(), @@ -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. diff --git a/src/config/mongoose_config_parser_toml.erl b/src/config/mongoose_config_parser_toml.erl index 2a2f21d6869..ec31bacf278 100644 --- a/src/config/mongoose_config_parser_toml.erl +++ b/src/config/mongoose_config_parser_toml.erl @@ -5,9 +5,6 @@ -export([parse_file/1]). -%% Utilities for section manipulation --export([process/3]). - -ifdef(TEST). -export([process/1, extract_errors/1]). @@ -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) @@ -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) -> @@ -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). diff --git a/src/config/mongoose_config_utils.erl b/src/config/mongoose_config_utils.erl index 364c2642b76..27566ec5695 100644 --- a/src/config/mongoose_config_utils.erl +++ b/src/config/mongoose_config_utils.erl @@ -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])}.