diff --git a/.gitignore b/.gitignore index 1b1b903..3946586 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .eunit +.tool-versions *.o *.beam *.plt diff --git a/sample-schemas/demo_schema.erl b/sample-schemas/demo_schema.erl index 7885563..353ea8c 100644 --- a/sample-schemas/demo_schema.erl +++ b/sample-schemas/demo_schema.erl @@ -7,10 +7,12 @@ -behaviour(hocon_schema). -type duration() :: integer(). +-type percent() :: float(). -typerefl_from_string({duration/0, emqx_schema, to_duration}). +-typerefl_from_string({percent/0, emqx_schema, to_percent}). --reflect_type([duration/0]). +-reflect_type([duration/0, percent/0]). -export([roots/0, fields/1, translations/0, translation/1]). @@ -35,6 +37,7 @@ fields("a_b") -> [ {"some_int", hoconsc:mk(integer(), #{mapping => "a_b.some_int", importance => hidden })} + , {"some_percent", fun some_percent/1} ]; fields("b") -> @@ -112,6 +115,10 @@ numbers(_) -> undefined. priv_duration(type) -> duration(); priv_duration(_) -> undefined. +some_percent(type) -> percent(); +some_percent(mapping) -> "a_b.some_percent"; +some_percent(_) -> undefined. + priv_bool(type) -> boolean(); priv_bool(_) -> undefined. diff --git a/src/hocon_postprocess.erl b/src/hocon_postprocess.erl index 3c2922f..bace2ff 100644 --- a/src/hocon_postprocess.erl +++ b/src/hocon_postprocess.erl @@ -131,10 +131,13 @@ percent(Other) -> Other. do_percent(Str) -> - {ok, MP} = re:compile("([0-9]+)(%)$"), + {ok, MP} = re:compile("([0-9.]+)(%)$"), case re_run_first(Str, MP) of {match, [Val, _Unit]} -> - list_to_integer(Val) / 100; + case string:to_integer(Val) of + {Int, []} -> Int / 100; + _ -> round(list_to_float(Val) * 100) / 10000 + end; _ -> Str end. diff --git a/test/hocon_tconf_tests.erl b/test/hocon_tconf_tests.erl index 7a5c5e9..7450d70 100644 --- a/test/hocon_tconf_tests.erl +++ b/test/hocon_tconf_tests.erl @@ -332,6 +332,18 @@ mapping_test_() -> F("foo.numbers=[1,2,3]") ), ?_assertEqual([{["a_b", "some_int"], 1}, Setting], F("a_b.some_int=1")), + ?_assertEqual([{["a_b", "some_percent"], 0.12}, Setting], F("a_b.some_percent=12%")), + ?_assertEqual([{["a_b", "some_percent"], 0.123}, Setting], F("a_b.some_percent=\"12.3%\"")), + ?_assertEqual( + [{["a_b", "some_percent"], 0.1234}, Setting], F("a_b.some_percent=\"12.34%\"") + ), + %% we only support 2 decimal places + ?_assertEqual( + [{["a_b", "some_percent"], 0.4321}, Setting], F("a_b.some_percent=\"43.214%\"") + ), + ?_assertEqual( + [{["a_b", "some_percent"], 0.1235}, Setting], F("a_b.some_percent=\"12.345%\"") + ), ?_assertEqual([Setting], F("foo.ref_x_y={some_int = 1}")), ?GEN_VALIDATION_ERR(_, F("foo.ref_x_y={some_int = aaa}")), ?_assertEqual(