Skip to content

Commit

Permalink
Keep maps (actually, structs) for oneof
Browse files Browse the repository at this point in the history
  • Loading branch information
v0idpwn committed Oct 20, 2024
1 parent 18ad14f commit 6f73187
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 7 deletions.
13 changes: 6 additions & 7 deletions lib/protobuf/encoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
11 changes: 11 additions & 0 deletions test/protobuf/encoder_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions test/support/test_msg.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand Down

0 comments on commit 6f73187

Please sign in to comment.