scala - reads - Cómo escribir un convertidor de escritura Play JSON para una clase de caso con un único miembro anulable
play json github (2)
En Play 2.3, tengo una clase de caso con un único miembro doble opcional:
case class SomeClass(foo: Option[Double])
Necesito un convertidor de escritura JSON que maneje el miembro como nulable:
implicit val someClassWrite: Writes[SomeClass] = ???
Los documentos Play proporcionan un ejemplo :
case class DisplayName(name:String)
implicit val displayNameWrite: Writes[DisplayName] = Writes {
(displayName: DisplayName) => JsString(displayName.name)
}
Pero lamentablemente no puedo entender cómo hacer esto para 1) una sola anulable y 2) una doble. ¿Algunas ideas? Gracias.
Actualización n. ° 1: la única solución que se me ocurre es esta:
implicit val someClassWrite: Writes[SomeClass] = Writes {
(someClass: SomeClass) => someClass.foo match {
case Some(f) => JsNumber(BigDecimal(f))
case _ => JsNull
}
Actualización # 2: Ignora mi solución. Travis Brown''s es el indicado.
La manera fácil es:
import play.api.libs.json.Json
implicit val fmt = Json.format[SomeClass]
Que usa una macro para generar automáticamente el formato json por usted. Beats implementando escribe directamente.
Writes
no es un functor covariante, por lo que no puede usar el map
, pero puede usar contramap
:
import play.api.libs.json._
import play.api.libs.functional.syntax._
implicit val someClassWrites: Writes[SomeClass] =
(__ / ''foo).writeNullable[Double].contramap(_.foo)
Si tiene más de un miembro, puede usar la sintaxis FunctionalBuilder
de Play:
case class AnotherClass(foo: Option[Double], bar: Option[String])
implicit val anotherClassWrites: Writes[AnotherClass] = (
(__ / ''foo).writeNullable[Double] and
(__ / ''bar).writeNullable[String]
)(ac => (ac.foo, ac.bar))
En el primer caso, el argumento de contramap
es solo una función del tipo que desea que Writes
para el tipo en las Writes
que llama el contramap
. En el segundo caso, la función al final es del objetivo ( AnotherClass
aquí) a una tupla de las instancias Writes
que ha creado and
(en este caso Option[Double]
y Option[String]
).