Inner structs don't obey defimpl Encoder rules
louiscb opened this issue · 3 comments
louiscb commented
Description of problem
When a struct contains an inner struct, both with Jsonrs.Encoder
definitions, the Jsonrs.encode
function will not pick up on the inner struct's definition.
Test recreating problem
This test fails when it should pass. The inner structs defimpl is not
defmodule SomeStruct do
defstruct [:field, :inner_struct]
end
defmodule InnerStruct do
defstruct [:field, :ignored_field]
end
defimpl Jsonrs.Encoder, for: SomeStruct do
def encode(%{field: f, inner_struct: is}) do
%{f: f, is: is}
end
end
defimpl Jsonrs.Encoder, for: InnerStruct do
def encode(%{field: f}) do
%{f: f}
end
end
test "protocols" do
is = %InnerStruct{field: "a", ignored_field: "b"}
val = %SomeStruct{
field: "a",
inner_struct: is
}
assert ~s({"f":"a"}) == Jsonrs.encode!(is)
assert ~s({"f":"a","is":{"f":"a"}}) ==
Jsonrs.encode!(val)
end
benhaney commented
To me, this is expected behavior. If you want custom encoding to continue descending through the return value of your custom encoder, your Encoder
impl for SomeStruct
would need to look something like
defimpl Jsonrs.Encoder, for: SomeStruct do
def encode(%{field: f, inner_struct: is}) do
%{f: f, is: is} |> Jsonrs.Encoder.encode()
end
end
which I believe is conceptually similar to what would be required with Jason or Poison.
louiscb commented
I see, makes sense.