Scala CI Release

play-json derivation

Provide derivation of Reads and Writes of play-json types, using magnolia

Install

  libraryDependencies += "com.github.fxhibon" %% "play-json-derived-play-2X" % "<latest-release>" 

How to use

  • for a complete examples, see the tests

In a few words, given:

sealed trait Tree[T]

case class Branch[T](left: Tree[T], right: Tree[T]) extends Tree[T]

case class Leaf[T](value: T) extends Tree[T]

one can derive for zero cost an instance of Reads or Writes for Tree[Int], assuming there is a Reads[Int] in the scope

import play.api.libs.json._
import com.github.fxhibon.json.derived.ReadsDerivation._
import com.github.fxhibon.json.derived.WritesDerivation._

val treeReads: Reads[Tree[Int]] = deriveReads[Tree[Int]]
val treeWrites: Writes[Tree[Int]] = deriveWrites[Tree[Int]]

val leaf: Tree[Int] = Json.parse("""{"type": "Leaf", "value": 123}""").as[Tree[Int]](treeReads)
// Leaf(123)

val json = treeWrites.writes(leaf)
// {"type": "Leaf", "value": 123}

The default behaviors to read/write type name and payload can be overloaded by providing implicit instances for respectively TypeNameReads, TypeNameWrites and PayloadPath

import play.api.libs.json._
import com.github.fxhibon.json.derived.ReadsDerivation._
import com.github.fxhibon.json.derived.WritesDerivation._

implicit val payloadPath: PayloadPath = PayloadPath(JsPath \ "data")
implicit val typeNameWrites: TypeNameWrites = TypeNameWrites((JsPath \ "custom_type_name").write[String])
implicit val typeNameReads: TypeNameReads = TypeNameReads((JsPath \ "custom_type_name").read[String])

val treeReads: Reads[Tree[Int]] = deriveReads[Tree[Int]]
val treeWrites: Writes[Tree[Int]] = deriveWrites[Tree[Int]]

val leaf: Tree[Int] = Json.parse("""{"custom_type_name": "Leaf", "data": {"value": 123}}""").as[Tree[Int]](treeReads)
// Leaf(123)

val json = treeWrites.writes(leaf)
// {"custom_type_name": "Leaf", "data": {"value": 123}}

I made sure that errors generated by failing Reads or Writes are close enough to what play-json macro's would have generated, so switching from play-json macro to this library should be seamless.

Features

  • derive Reads
  • derive Writes
  • support customization of type name Reads / Writes
  • support customization of payload Reads / Writes

Resources