13

I have a struct which already has @derive Jason.Encoder but some fields in that struct are tuples, and for this reason cannot encode the struct, how can I fix that :/

UPDATE

I have used the approach that mentioned below with implementing a protocol. One important thing to note about this approach is that it will change the encoding for the whole project, just be careful with that !

Tano
  • 1,285
  • 1
  • 18
  • 38
  • Hi--perhaps you could supply some example of your code? Maybe you could give us more specifics on what's not working? It looks like you've gotten an answer but for others who may find this question later on, more details would be helpful. – Onorio Catenacci May 16 '19 at 13:47

3 Answers3

17

If you do need to encode tuples as a list type, this works:

defmodule TupleEncoder do
  alias Jason.Encoder

  defimpl Encoder, for: Tuple do
    def encode(data, options) when is_tuple(data) do
      data
      |> Tuple.to_list()
      |> Encoder.List.encode(options)
    end
  end
end

You should be able to use a similar pattern to convert it to another primitive structure as needed.

bxdoan
  • 1,349
  • 8
  • 22
9

Have a look at the documentation for how you need to implement the encode/2 function: https://hexdocs.pm/jason/Jason.Encoder.html

As part of your implementation, you need to decide how you want to encode a tuple since it doesn't have an analog in JSON. An array is probably the easiest option, so you could do mytuple |> Tuple.to_list

mroach
  • 2,403
  • 1
  • 22
  • 29
0

I found that @bxdoan's solution did not work if the tuple includes elements that had original defimpl extensions (for example the exemplar one for MapSet, Range, and Stream). I changed it to:

defimpl Jason.Encoder, for: Tuple do
  def encode(data, opts) when is_tuple(data) do
    Jason.Encode.list(Tuple.to_list(data), opts)
  end
end

and that worked better.

Travis Griggs
  • 21,522
  • 19
  • 91
  • 167