diff --git a/src/gpb_gen_verifiers.erl b/src/gpb_gen_verifiers.erl index 3d841640..5b0f6f3c 100644 --- a/src/gpb_gen_verifiers.erl +++ b/src/gpb_gen_verifiers.erl @@ -655,7 +655,11 @@ field_oneof_omitted_flat_verifier(MsgName, FName, OFields, FVar, MsgVar, TrUserDataVar, AnRes, Opts) -> %% FIXME: Verify at most one oneof field is set - OFNames = gpb_lib:get_field_names(OFields), + OFNames0 = gpb_lib:get_field_names(OFields), + OFNames = case gpb_lib:get_maps_key_type_by_opts(Opts) of + atom -> OFNames0; + binary -> lists:map(fun(X) -> atom_to_binary(X, utf8) end, OFNames0) + end, ?expr( case 'M' of '#{OFName := OFVar}' -> @@ -958,6 +962,7 @@ atom_to_stree(Atom) -> erl_syntax:atom(Atom). atom_to_binary_string_stree(Atom) -> + Cs = atom_to_list(Atom), erl_syntax:binary( [erl_syntax:binary_field( - erl_syntax:string(atom_to_list(Atom)))]). + erl_syntax:integer(C)) || C <- Cs]). diff --git a/src/gpb_lib.erl b/src/gpb_lib.erl index 95610a80..43fb2d04 100644 --- a/src/gpb_lib.erl +++ b/src/gpb_lib.erl @@ -614,9 +614,10 @@ mapkey_literal_by_opts(Opts) -> fun(Atom) -> erl_syntax:atom(Atom) end; binary -> fun(Atom) -> + Cs = atom_to_list(Atom), erl_syntax:binary( [erl_syntax:binary_field( - erl_syntax:string(atom_to_list(Atom)))]) + erl_syntax:integer(C)) || C <- Cs]) end end. @@ -626,11 +627,9 @@ mapkey_expr_by_opts(Opts) -> fun(Expr) -> Expr end; binary -> fun(Expr) -> - erl_syntax:binary( - [erl_syntax:binary_field( - erl_syntax:application(erl_syntax:atom(erlang), - erl_syntax:atom(atom_to_list), - [Expr]))]) + erl_syntax:application(erl_syntax:atom(erlang), + erl_syntax:atom(atom_to_binary), + [Expr, erl_syntax:atom(utf8)]) end end. diff --git a/test/gpb_compile_maps_tests.erl b/test/gpb_compile_maps_tests.erl index 13c50a60..a217cee4 100644 --- a/test/gpb_compile_maps_tests.erl +++ b/test/gpb_compile_maps_tests.erl @@ -676,6 +676,33 @@ flat_oneof_with_translation_with_typespec_maps_test_aux() -> ]), ?assert(gpb_lib:is_substr("a1=>string()", strip_ws(Erl))). +flat_oneof_with_maps_key_type_binary_test() -> + M = compile_iolist([ "message test {" + , " map args = 1;" + , "}" + , "message union {" + , " oneof u {" + , " int32 a = 1;" + , " string b = 2;" + , " }" + , "}" + ], + [{maps, true}, + {maps_oneof, flat}, + {maps_key_type, binary}, + {maps_unset_optional, omitted}, + strings_as_binaries, + {verify, always}]), + MapInput1 = #{<<"args">> => #{<<"hello">> => <<"world">>}}, + MapData1 = M:encode_msg(MapInput1, test), + ?assertEqual(MapInput1, M:decode_msg(MapData1, test)), + UnionInput1 = #{<<"a">> => 1}, + UnionData1 = M:encode_msg(UnionInput1, union), + ?assertEqual(UnionInput1, M:decode_msg(UnionData1, union)), + UnionInput2 = #{<<"b">> => <<"hello">>}, + UnionData2 = M:encode_msg(UnionInput2, union), + ?assertEqual(UnionInput2, M:decode_msg(UnionData2, union)), + unload_code(M). strip_ws(B) when is_list(B) -> binary_to_list(