Search code examples
jsonscalajsonserializerscala-picklingscala-2.11

Scala Pickling for Json serialization and deserialization?


For my project, dijon, I was wondering if it is possible to use Scala pickling for JSON serialization and deserialization. Specifically, I want something like this def toJsonString(json: JSON, prettyPrint: Boolean = false): String and def fromJsonString(json: String): JSON. How can I use pickling to create these two helper methods?


Solution

  • It really depends on what is most convenient for your use. These are rough sketches of the choices you have:

     import scala.pickling._, json._    
    
     // Uses macros implicitly on Scope
     def toJSONString[A](obj: A, prettyPrint: Boolean = false)(implicit pickler: A => JSONPickle) = {
        val json = pickler(obj)
        myPrettyPrinter.print(json.value, prettyPrint)
     }
    
     // Uses macros defined elsewhere
     def toJSONString(obj: Any, prettyPrint: Boolean = false) = {
        val json = classToPicklerMap(obj.getClass)(obj)
        myPrettyPrinter.print(json.value, prettyPrint)
     }
    
     // Uses runtime reflection
     def toJSONString(obj: Any, prettyPrint: Boolean = false) = {
        val json = obj.pickle
        myPrettyPrinter.print(json.value, prettyPrint)
     }
    
     // Uses macros implicitly on scope
     def fromJSONString[A](json: String)(implicit unpickler: JSONPickle => A): A = {
        unpickler(JSONPickle(json))
     }
    
     // Uses macros defined elsewhere #1
     def fromJSONString[A](json: String)(implicit c: ClassTag[A]) = {
        classnameToUnpicklerMap(c.runtimeClass.getName)(json).asInstanceOf[A]
     }
    
     // Uses macros defined elsewhere #2
     def fromJSONString(json: String): Any = {
        val className = parseClassName(json) // Class name is stored in "tpe" field in the JSON    
        classnameToUnpicklerMap(className)(json)
     }
    
     // Uses runtime reflection
     def fromJSONString(json: String) = JSONPickler(json).unpickle