diff --git a/src/gmser_dyn.erl b/src/gmser_dyn.erl index 2dd4e37..78a0c82 100644 --- a/src/gmser_dyn.erl +++ b/src/gmser_dyn.erl @@ -330,13 +330,13 @@ encode_from_template(Type, List, E, Vsn, Types) when is_list(Type), is_list(List encode_fields(Type, List, E, Vsn, Types); encode_from_template(label, V, E, _, Types) -> assert_type(is_atom(V), label, V), - emit(E, label, Types, - case find_cached_label(V, Types) of - error -> - encode_basic(label, V, E, Types); - {ok, Code} when is_integer(Code) -> - [encode_basic(int, Code)] - end); + case find_cached_label(V, Types) of + error -> + encode_basic(label, V, E, Types); + {ok, Code} when is_integer(Code) -> + emit(E, label, Types, + [encode_basic(int, Code)]) + end; encode_from_template(Type, V, E, _, Types) when Type == id ; Type == binary ; Type == bool @@ -461,11 +461,14 @@ register_types(Types) when is_map(Types) -> Rev = rev_codes(Codes), Templates = maps:get(templates, Types, #{}), Labels = maps:get(labels, Types, #{}), - #{codes := Codes0, rev := Rev0, labels := Labels0, templates := Templates0} = + Options = maps:get(options, Types, #{}), + #{codes := Codes0, rev := Rev0, labels := Labels0, + templates := Templates0, options := Options0} = dynamic_types(), Merged = #{ codes => maps:merge(Codes0, Codes) , rev => maps:merge(Rev0, Rev) , templates => maps:merge(Templates0, Templates) + , options => maps:merge(Options0, Options) , labels => maps:merge(Labels0, Labels) }, assert_sizes(Merged), assert_mappings(Merged), @@ -650,6 +653,7 @@ user_types_test_() -> , ?_test(t_reg_template_vsnd_fun()) , ?_test(t_reg_label_cache()) , ?_test(t_reg_label_cache2()) + , ?_test(t_reg_options()) ]}. dynamic_types_test_() -> @@ -657,6 +661,7 @@ dynamic_types_test_() -> , ?_test(t_typed_map()) , ?_test(t_alts()) , ?_test(t_anyints()) + , ?_test(t_missing_labels()) ]. t_round_trip(T) -> @@ -750,6 +755,13 @@ t_reg_label_cache2() -> [<<0>>,<<1>>,[<<3,235>>,[[<<49>>],[<<49>>]]]] = Enc, _Tup = gmser_dyn:decode(Enc). +t_reg_options() -> + register_types(set_opts(#{missing_labels => convert})), + [Dyn,Vsn,[Am,<<"random">>]] = gmser_dyn:encode(random), + EncNewAm = [Dyn,Vsn,[Am,<<"foo12345">>]], + <<"foo12345">> = gmser_dyn:decode(EncNewAm), + ok. + t_typed_map() -> Term = #{a => 13, {key,1} => [a]}, Enc = encode_typed(#{items => [{a,int},{{key,1},[label]}]}, Term), @@ -765,4 +777,13 @@ t_anyints() -> t_round_trip_typed(anyint, 5), ok. +t_missing_labels() -> + [Dyn,Vsn,[Am,<<"random">>]] = gmser_dyn:encode(random), + EncNewAm = [Dyn,Vsn,[Am,<<"flurbee">>]], + ?assertError(badarg, gmser_dyn:decode(EncNewAm)), + ?assertError(badarg, gmser_dyn:decode(EncNewAm, set_opts(#{missing_labels => fail}))), + <<"flurbee">> = gmser_dyn:decode(EncNewAm, set_opts(#{missing_labels => convert})), + true = is_atom(gmser_dyn:decode(EncNewAm, set_opts(#{missing_labels => create}))), + ok. + -endif.