Skip to content

Commit 1636b66

Browse files
Fix JSON encoding of proto3 optional non-nil defaults (#359)
Co-authored-by: Andrea Leopardi <[email protected]>
1 parent 51f12a0 commit 1636b66

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

lib/protobuf/json/encode.ex

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,19 @@ defmodule Protobuf.JSON.Encode do
162162
defp encode_regular_fields(struct, %{field_props: field_props}, opts) do
163163
for {_field_num, %{name_atom: name, oneof: nil} = prop} <- field_props,
164164
%{^name => value} = struct,
165-
opts[:emit_unpopulated] || !default?(prop, value) do
165+
emit?(prop, value) || opts[:emit_unpopulated] do
166166
encode_field(prop, value, opts)
167167
end
168168
end
169169

170+
defp emit?(_prop, nil) do
171+
false
172+
end
173+
174+
defp emit?(prop, value) do
175+
if default?(prop, value), do: prop.proto3_optional?, else: true
176+
end
177+
170178
defp encode_oneof_fields(struct, message_props, opts) do
171179
%{field_tags: field_tags, field_props: field_props, oneof: oneofs} = message_props
172180

test/protobuf/json/decode_test.exs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,26 @@ defmodule Protobuf.JSON.DecodeTest do
653653
%ContainsTransformModule{field: nil}
654654
end
655655

656+
test "decodes nil for proto3" do
657+
data = %{
658+
"b" => "A"
659+
}
660+
661+
assert decode(data, TestMsg.Proto3Optional) ==
662+
{:ok, %TestMsg.Proto3Optional{a: nil, b: "A", c: nil}}
663+
end
664+
665+
test "decodes default values for proto3 optional" do
666+
data = %{
667+
"a" => 0,
668+
"b" => "A",
669+
"c" => "UNKNOWN"
670+
}
671+
672+
assert decode(data, TestMsg.Proto3Optional) ==
673+
{:ok, %TestMsg.Proto3Optional{a: 0, b: "A", c: :UNKNOWN}}
674+
end
675+
656676
describe "Google types" do
657677
test "Google.Protobuf.Empty" do
658678
data = %{}

test/protobuf/json/encode_test.exs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ defmodule Protobuf.JSON.EncodeTest do
1414
Scalars
1515
}
1616

17+
test "encodes proto3 optional fields zero values" do
18+
message = %TestMsg.Proto3Optional{a: 0, c: :UNKNOWN}
19+
assert encode(message) == %{"a" => 0, "c" => :UNKNOWN}
20+
end
21+
22+
test "skips a proto3 optional field with a nil value" do
23+
message = %TestMsg.Proto3Optional{a: nil, c: nil}
24+
assert encode(message) == %{}
25+
end
26+
1727
test "encodes strings and booleans as they are" do
1828
message = %Scalars{string: "エリクサー", bool: true}
1929
assert encode(message) == %{"string" => "エリクサー", "bool" => true}

0 commit comments

Comments
 (0)