Skip to content

Instantly share code, notes, and snippets.

@jrudolph
Created June 2, 2014 12:21
Show Gist options
  • Select an option

  • Save jrudolph/f2d0825aac74ed81c92a to your computer and use it in GitHub Desktop.

Select an option

Save jrudolph/f2d0825aac74ed81c92a to your computer and use it in GitHub Desktop.
spray-json: JsonFormat for class hierarchy
import spray.json._
object TestJsonClassHierarchyFormat extends App {
sealed trait Animal extends Product
case class Dog(name: String, age: Int) extends Animal
case class Cat(name: String, catchesBirds: Boolean)extends Animal
import DefaultJsonProtocol._
implicit val dogFormat = jsonFormat2(Dog)
implicit val catFormat = jsonFormat2(Cat)
// format that discriminates based on an additional
// field "type" that can either be "Cat" or "Dog"
implicit val animalFormat = new RootJsonFormat[Animal] {
def write(obj: Animal): JsValue =
JsObject((obj match {
case c: Cat => c.toJson
case d: Dog => d.toJson
}).asJsObject.fields + ("type" -> JsString(obj.productPrefix)))
def read(json: JsValue): Animal =
json.asJsObject.getFields("type") match {
case Seq(JsString("Cat")) => json.convertTo[Cat]
case Seq(JsString("Dog")) => json.convertTo[Dog]
}
}
val a: Animal = Dog("Wuff", 23)
println(a.toJson)
println(a.toJson.convertTo[Animal])
println("""{"type": "Dog", "name": "Wuff", "age": 23}""".parseJson.convertTo[Animal])
println("""{"type": "Cat", "name": "Meow", "catchesBirds": true}""".parseJson.convertTo[Animal])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment