Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ordering keys when encoding a map to json with Poison

For reading purposes I would like to have a specific key order into the json file.

I know that map's key doesn't have any order and then we should not rely on that, but since Poison is not able to encode proplists I don't see how to do this.

iex(1)> %{from: "EUR", to: "USD", rate: 0.845} |> Poison.encode!
"{\"to\":\"USD\",\"rate\":0.845,\"from\":\"EUR\"}"

The result I would like is :

"{\"from\":\"EUR\", \"to\":\"USD\", \"rate\":0.845}"

Which structure should I use in order to achieve this with Poison ?

like image 486
TheSquad Avatar asked May 26 '16 09:05

TheSquad


1 Answers

Are you sure you want to do this? Probably the least bad way to do it would be to define a struct for your map, and then implement the Poison encode protocol for that struct.

It might look something like this...

defmodule Currency do
    defstruct from: "", to: "", rate: 0
end

then somewhere in your project implement the protocol

defimpl Poison.Encoder, for: Currency do
  def encode(%Currency{from: from, to: to, rate: rate}, _options) do
    """
      {"from": #{from}, "to": #{to}, "rate": #{rate}}
    """
  end
end

and then

Poison.encode!(%Currency{from: "USD", to: "EUR", rate: .845})

All that being said, I'd really, really recommend against doing this. Ordered maps are always a terrible idea, and lead to some really brittle and confusing behavior.

Consider using something that's actually ordered, like a list of lists

like image 116
rozap Avatar answered Oct 04 '22 07:10

rozap