ScalaのArgonautを触ってみた

最近、 Argonaut: Purely Functional JSON in Scala というライブラリを興味本位で触っているのでメモ。

利用したライブラリのバージョン

"io.argonaut" %% "argonaut" % "6.0.4"
"com.github.nscala-time" %% "nscala-time" % "1.2.0"

サンプル

本家サイトのドキュメントを眺めればイメージは掴めると思います。

というわけで、まずはドキュメントを読みましょう。

エンコード・デコード

org.joda.time.DateTime などの型もデコードしたくなったので試しに定義してみました。

(import は省いてます)

implicit def DateTimeDecodeJson: DecodeJson[DateTime] =
  DecodeJson.optionDecoder(_.string.flatMap(_.toDateTimeOption), "org.joda.time.DateTime")

implicit def DateTimeEncodeJson: EncodeJson[DateTime] =
  EncodeJson(a => jString(a.toString))

optionDecoder の第一引数が Json => Option[A] なので、ここに変換関数を渡す方法でも定義できそう。

Case Classへのデコードなどはドキュメントに書かれているので略。

代数的データ型をエンコード・デコード

||| を使えば、最初に成功した結果が返るので、表現できそうな気がします。

trait Hoge
case class Fuga(foo: String, bar: Int) extends Hoge
case class Piyo(buz: Double, qux: Option[String]) extends Hoge

implicit def HogeDecodeJson: DecodeJson[Hoge] =
  jdecode2L(Fuga.apply)("foo", "bar") ||| jdecode2L(Piyo.apply)("buz", "qux")

これ、もっと他に方法がありそう…要調査。

直接関係はしないですが、Optionなどよく使われる型に関しては既にデコーダ・エンコーダが定義されているので、楽ですね。

利点?

Scalazに依存しているので、Scalazに依存しているライブラリとの相性は良いのではないでしょうか。