thbar
Mix.install/2 and Jason.encode! of non-owned structs
I have been trying to JSON-encode structs defined in ExTwitter, such as ExTwitter.Model.Relationship for instance (the goal is to serialise them in a format which can be parsed from any language, or by a human easily), in a Mix.install/2 script.
I first learned that structs must be handled a bit specifically in such scripts (see Mix.install and structs).
After following the advice given, I had the expected error message:
(Protocol.UndefinedError) protocol Jason.Encoder not implemented for #ExTwitter.Model.Relationship<connections: nil, id: nil, id_str: nil, name: nil, screen_name: "TOTO", ...> of type ExTwitter.Model.Relationship (a struct), Jason.Encoder protocol must always be explicitly implemented.
If you own the struct, you can derive the implementation specifying which fields should be encoded to JSON:
@derive {Jason.Encoder, only: [....]}
defstruct ...
It is also possible to encode all fields, although this should be used carefully to avoid accidentally leaking private information when new fields are added:
@derive Jason.Encoder
defstruct ...
Finally, if you don't own the struct you want to encode to JSON, you may use Protocol.derive/3 placed outside of any module:
Protocol.derive(Jason.Encoder, NameOfTheStruct, only: [...])
Protocol.derive(Jason.Encoder, NameOfTheStruct)
. This protocol is implemented for the following type(s): Any, Atom, BitString, Date, DateTime, Decimal, Float, Integer, Jason.Fragment, Jason.OrderedObject, List, Map, NaiveDateTime, Time
Since I do not own the struct I want to encode, I attempted to run Protocol.derive(Jason.Encoder, ExTwitter.Model.Relationship) from inside a compiled method, but this does not work either (and the error message remains).
What works, so far, is leveraging Map.from_struct.
Is this a caveat we want to see in the documentation, or is there maybe a way to make it work without Map.from_struct, which I didn’t see?
Thanks!
Most Liked
lud
There is an option in Mix.install to prevent protocol consolidation. That should allow you to implement it.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









