Deriving Jason.Encoder
by default excludes the :__struct__
key. Suppose I wanted to create a use
able module that, when use
d, derives Jason.Encoder
with all keys, including :__struct__
. How to do that? I tried the following:
defmodule JsonWithStruct do
defmacro __using__(_) do
quote do
@before_compile unquote(__MODULE__)
end
end
defmacro __before_compile__(_) do
quote do
@derive IO.inspect({Jason.Encoder, only: Map.keys(@__struct__)})
end
end
end
defmodule SomeStruct do
use JsonWithStruct
defstruct [:foo, :bar]
end
When compiling, it outputs:
{Jason.Encoder, [only: [:__struct__, :bar, :foo]]}
as expected. However, the protocol is still somehow not implemented.
iex(74)> %SomeStruct{} |> Jason.encode!()
** (Protocol.UndefinedError) protocol Jason.Encoder not implemented for %SomeStruct{bar: nil, foo: nil} of type SomeStruct (a struct), Jason.Encoder protocol must always be explicitly implemented.
iex(73)> Jason.Encoder.impl_for %SomeStruct{}
Jason.Encoder.Any
Why is it not working? I suspect it has to do with protocol compilation having different nuances than regular modules?