From 6f73187d880262bce4dc787033d733df5ca0d767 Mon Sep 17 00:00:00 2001 From: v0idpwn Date: Sun, 20 Oct 2024 17:14:25 -0300 Subject: [PATCH] Keep maps (actually, structs) for oneof --- lib/protobuf/encoder.ex | 13 ++++++------- test/protobuf/encoder_test.exs | 11 +++++++++++ test/support/test_msg.ex | 2 ++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/lib/protobuf/encoder.ex b/lib/protobuf/encoder.ex index 69921269..6db7acce 100644 --- a/lib/protobuf/encoder.ex +++ b/lib/protobuf/encoder.ex @@ -73,19 +73,18 @@ defmodule Protobuf.Encoder do "Got error when encoding #{inspect(struct.__struct__)}##{prop.name_atom}: #{Exception.format(:error, error)}" end + defp skip_field?(_syntax, val, %FieldProps{oneof: oneof}) when not is_nil(oneof), do: is_nil(val) defp skip_field?(_syntax, [], _prop), do: true defp skip_field?(_syntax, val, _prop) when is_map(val), do: map_size(val) == 0 defp skip_field?(:proto2, nil, %FieldProps{optional?: optional?}), do: optional? defp skip_field?(:proto2, value, %FieldProps{default: value, oneof: nil}), do: true - defp skip_field?(:proto3, val, %FieldProps{proto3_optional?: true}), - do: is_nil(val) - + defp skip_field?(:proto3, val, %FieldProps{proto3_optional?: true}), do: is_nil(val) defp skip_field?(:proto3, nil, _prop), do: true - defp skip_field?(:proto3, 0, %FieldProps{oneof: nil}), do: true - defp skip_field?(:proto3, +0.0, %FieldProps{oneof: nil}), do: true - defp skip_field?(:proto3, "", %FieldProps{oneof: nil}), do: true - defp skip_field?(:proto3, false, %FieldProps{oneof: nil}), do: true + defp skip_field?(:proto3, 0, _prop), do: true + defp skip_field?(:proto3, +0.0, _prop), do: true + defp skip_field?(:proto3, "", _prop), do: true + defp skip_field?(:proto3, false, _prop), do: true defp skip_field?(_syntax, _val, _prop), do: false defp encode_field( diff --git a/test/protobuf/encoder_test.exs b/test/protobuf/encoder_test.exs index 12a9f32b..af486358 100644 --- a/test/protobuf/encoder_test.exs +++ b/test/protobuf/encoder_test.exs @@ -146,6 +146,10 @@ defmodule Protobuf.EncoderTest do msg = %TestMsg.Oneof{first: {:e, :UNKNOWN}} assert Encoder.encode(msg) == <<48, 0>> assert TestMsg.Oneof.decode(<<48, 0>>) == msg + # map + msg = %TestMsg.Oneof{first: {:f, %{}}} + assert Encoder.encode(msg) == <<58, 0>> + assert TestMsg.Oneof.decode(<<58, 0>>) == %TestMsg.Oneof{first: {:f, %TestMsg.Foo.Bar{}}} # proto3 # int and string @@ -159,6 +163,13 @@ defmodule Protobuf.EncoderTest do msg = %TestMsg.OneofProto3{first: {:e, :UNKNOWN}} assert Encoder.encode(msg) == <<48, 0>> assert TestMsg.OneofProto3.decode(<<48, 0>>) == msg + # map + msg = %TestMsg.OneofProto3{first: {:f, %{}}} + assert Encoder.encode(msg) == <<58, 0>> + + assert TestMsg.OneofProto3.decode(<<58, 0>>) == %TestMsg.OneofProto3{ + first: {:f, %TestMsg.Foo.Bar{}} + } end test "encodes proto3 optional fields zero values" do diff --git a/test/support/test_msg.ex b/test/support/test_msg.ex index 0da209c4..5403833c 100644 --- a/test/support/test_msg.ex +++ b/test/support/test_msg.ex @@ -113,6 +113,7 @@ defmodule TestMsg do field :c, 3, optional: true, type: :int32, oneof: 1 field :d, 4, optional: true, type: :string, oneof: 1 field :e, 6, optional: true, type: EnumFoo, enum: true, default: :A, oneof: 0 + field :f, 7, optional: true, type: Foo.Bar, oneof: 0 field :other, 5, optional: true, type: :string end @@ -127,6 +128,7 @@ defmodule TestMsg do field :c, 3, optional: true, type: :int32, oneof: 1 field :d, 4, optional: true, type: :string, oneof: 1 field :e, 6, type: EnumFoo, enum: true, oneof: 0 + field :f, 7, optional: true, type: Foo.Bar, oneof: 0 field :other, 5, optional: true, type: :string end