meh / jazz

Yet another library to handle JSON in Elixir.
61 stars 21 forks source link

Why are are only the nil, true, false atoms matched in Encoder? #12

Closed BjRo closed 10 years ago

BjRo commented 10 years ago

Hi just a question, because I stumbled over it while coding on a JSON layer in my phoenix app.

Why is the Jazz.Encoder protocol implementation for Atom limited to true, false, nil?

I certainly see the need to handle nil separately, but wouldn't a more general implementation like

  def to_json(f, _) do
    Atom.to_string(f)
  end

be a bit user friendlier?

I'm asking because I wanted to serialize a map that contains atoms as values (for instance like %{id: :not_found} and was surprised that this is currently not possible ....

Cheerio Björn

meh commented 10 years ago

Because true encodes to true, false to false and nil to null.

Atoms shouldn't really be converted to strings in my opinion (they're only converted when they are keys).

If it's a struct you have you should defimpl JSON.Encoder for that, if it's just a raw map you can just for { key, value } <- map, into: %{}, do: { key, Atom.to_string(value) } |> JSON.encode.

BjRo commented 10 years ago

Atoms shouldn't really be converted to strings in my opinion Can you elaborate on that?

meh commented 10 years ago

They don't have a direct decoding, you'd encode a map with atoms as values, and get back a decoded map with strings as values.

BjRo commented 10 years ago

Ok, thx for the clarification. You want to be symmetric in encoding/decoding.

You do already serialize atoms to strings in maps though....

f = Jazz.encode! %{foo: "bar"}
#=> "{\"foo\":\"bar\"}" 
Jazz.decode! f
#=> %{ "foo" => "bar" }

and since you already provide the means to let the client decide how he wants keys to be parsed (Jazz.decode! x, keys: :atoms) I think it would be consistent to

Anyway, since Jazz is awesome I helped myself by overriding the Jazz.Encoder protocol for Atom in my project :-)

meh commented 10 years ago

Yes, keys are a different matter because both maps and structs use atoms as keys, and there are options for converting the keys to atoms because they're handled specially since converting strings to atoms without some checking is going to dos your application if the input is not checked.

In general you should use structs if you want special encoding/decoding behavior instead of using raw maps.

batizhevsky commented 7 years ago

Thanks @meh for the library. But what about this point, I'm on @BjRo side, because JSON is a format for strict serialization/desalinization and it's not the main purpose for this library. Anyway you loose types then convert to json, but why not to convert atoms to string?