play-jsonでReads/Writes/Formatを定義しなくてもよくする

play-jsonはReads/Writes/Formatを定義するのが面倒とよく言われるので、shapelessの練習も兼ねて作ってみました。

https://github.com/tototoshi/play-json-generic

scala> import play.api.libs.json._
import play.api.libs.json._

scala> case class Person(firstName: String, lastName: String, friends: List[Person])
defined class Person

scala> val people = Person("John",
     |                     "Lennon",
     |                     List(Person("Paul", "McCartney", Nil),
     |                          Person("George", "Harrison", Nil),
     |                          Person("Ringo", "Starr", Nil)))
people: Person = Person(John,Lennon,List(Person(Paul,McCartney,List()), Person(George,Harrison,List()), Person(Ringo,Starr,List())))

scala> Json.prettyPrint(Json.toJson(people))
<console>:18: error: No Json serializer found for type Person. Try to implement an implicit Writes or Format for this type.
       Json.prettyPrint(Json.toJson(people))
                                   ^

Reads/Writes/Formatを定義していないcase classをシリアライズしようとすると当然こんなエラーが出ますが、

import com.github.tototoshi.play.json.generic._ することでシリアライズ/デシリアライズできるようになります。

scala> import com.github.tototoshi.play.json.generic._
import com.github.tototoshi.play.json.generic._

scala> Json.prettyPrint(Json.toJson(people))
res1: String =
{
  "firstName" : "John",
  "lastName" : "Lennon",
  "friends" : [ {
    "firstName" : "Paul",
    "lastName" : "McCartney",
    "friends" : [ ]
  }, {
    "firstName" : "George",
    "lastName" : "Harrison",
    "friends" : [ ]
  }, {
    "firstName" : "Ringo",
    "lastName" : "Starr",
    "friends" : [ ]
  } ]
}

scala> Json.parse(res1).as[Person]
res2: Person = Person(John,Lennon,List(Person(Paul,McCartney,List()), Person(George,Harrison,List()), Person(Ringo,Starr,List())))

play-jsonJson.formatとかはマクロで実装されているので、そのマクロのためのオプションとかには一部対応できていないです。JsonNamingには対応できました。

Shapeless使ってみたいという人には The Type Astronaut's Guide to Shapeless - Underscore がすごくわかりやすくてオススメです。

追記

指摘されて気づいたんですが、HListを使っているので23個以上のフィールドを持つcase classにまつわる問題が解決しちゃってました。

https://github.com/tototoshi/play-json-generic/commit/0382c149efb4ed9fd4b4bcea99841641f2ca7949