Facade for serialization of supported ASTs?
Escalating Twitter discussion discussion beyond 140 characters:
I created jawn-streamz for parsing scalaz-streams of ByteVectors to any Jawn-supported JSON AST. I think it could make a good Jawn module, but I also have the use case of serializing JSON back to ByteVectors. It would be splendid if this could also be done through a facade, and keep streamz support shielded from the Great JSON Framework Holy War.
Open questions:
- Would serialization be in scope for Jawn, or is that bloat?
- If in scope, what types are targeted for serialization? Parser supports String, File, Channel, ByteBuffer, and scalaz.stream.Process. Symmetry is neat.
- What additions to the facade would be necessary to support those targets?
- Should a serialization facade offer options for pretty-printing, compact, etc.?
I'm going to try and put this parser into muster, which in turn will be used in json4s. https://github.com/json4s/muster
I am totally open to serialization from "raw" ASTs (I don't want to handle any object-mapping in Jawn). So it's definitely in-scope if we think we can do it well.
I think symmetry around targets makes sense, with the caveat that I am not sure if there is a canonical byte vector implementation?
As far as facade additions, I feel like we'd probably need two layers (sort of like how we have Parser[J] but also Facade[J]). I don't have a totally clear picture but I don't think it would necessarily be that hard, with that caveat that using "the most efficient" method of iteration over collections might necessitate more verbose definition.
What do you think? I guess my biggest question for you is about byte vectors.
The scodec ByteVector is gaining traction. Its used in a few typelevel projects right now, and we are using it in http4s and loving it. I suppose that doesn't make it canonical, but its the best thing around that I'm aware of.
Ah, OK, I'll definitely take a look. Thanks!
ByteVector was the obvious choice for jawn-streamz, because scalaz-stream already uses it extensively. A reactive-stream of Akka's ByteStrings might appeal to a different audience. I like that jawn-parser's lone dependency is scala-library, with more exotic targets integrated via modules. That same delineation makes sense to me for serialization.
And +1 to avoiding object mapping in Jawn.
We might choose to provide something simpler that could be mapped to ByteVector. For example, List[ByteBuffer] would not be a bad choice (since we would not be doing any truncation, but only appending). I'd probably implement that using ListBuffer and then converting to List.
We could also provide Stream[ByteBuffer] (or similar) for rendering-as-you-go.
I understand it's not the goal of jawn, but you can now also do object mapping. https://github.com/json4s/muster/blob/jawn/codecs/jawn/src/main/scala/muster/codec/jawn/jawn_input.scala
Awesome! Eventually I'll add a section to the README linking to muster.
I'd like this too =) I just C&Ped the bulk of the jawn serializer in upickle, just because I didn't want to pull in the bulk of Spire just to serialize some ASTs
Note: muster is now unmaintained, but it does implement this rendering for the ASTs: https://github.com/json4s/muster/blob/4816c14045e9d9609959e453636d6324b7dbf720/core/src/main/scala/muster/output/output.scala
If you're still willing to consider scope creep from abstract parser to abstract codec, I can look into scavenging that into a pull request. That would let me finish the other half of the jawn-streamz project.
I have something in-progress working on this. I'll look at it a bit more and comment here.
For the record I ended up forking Jawn into uJson, which has support for serializing every AST supported by jawn via the Facade interface (renamed to Visitor)