Background
I am trying to encode a structure into json format using the Jason library. However, this is not working as expected.
Code
Let’s assume I have this struct:
defmodule Test do defstruct [:foo, :bar, :baz] end
And that when using Jason.enconde(%Test{foo: 1, bar: 2, baz:3 })
I want this json to be created:
%{"foo" => 1, "banana" => 5}
Error
It is my understanding that to achieve this I need to implement the Jason.Enconder
protocol in my struct:
https://hexdocs.pm/jason/Jason.Encoder.html
defmodule Test do defstruct [:foo, :bar, :baz] defimpl Jason.Encoder do @impl Jason.Encoder def encode(value, opts) do Jason.Encode.map(%{foo: Map.get(value, :foo), banana: Map.get(value, :bar, 0) + Map.get(value, :baz, 0)}, opts) end end end
However, this will not work:
Jason.encode(%Test{foo: 1, bar: 2, baz: 3}) {:error, %Protocol.UndefinedError{ description: "Jason.Encoder protocol must always be explicitly implemented.\n\nIf you own the struct, you can derive the implementation specifying which fields should be encoded to JSON:\n\n @derive {Jason.Encoder, only: [....]}\n defstruct ...\n\nIt is also possible to encode all fields, although this should be used carefully to avoid accidentally leaking private information when new fields are added:\n\n @derive Jason.Encoder\n defstruct ...\n\nFinally, if you don't own the struct you want to encode to JSON, you may use Protocol.derive/3 placed outside of any module:\n\n Protocol.derive(Jason.Encoder, NameOfTheStruct, only: [...])\n Protocol.derive(Jason.Encoder, NameOfTheStruct)\n", protocol: Jason.Encoder, value: %Test{bar: 2, baz: 3, foo: 1} }}
From what I understand, it looks like I can only select/exclude keys to serialize, I cannot transform/add new keys.
Since I own the structure in question, using Protocol.derive
is not necessary.
However I fail to understand how I can leverage the Jason.Encoder
protocol to achieve what I want.
Questions
- Is my objective possible using the Jason library, or is this a limitation?
- Am I miss understanding the documentation and doing something incorrect?