Providing Implicit Value for Singletones in the Play Json Library

I have the following configuration:

sealed trait Status case object Edited extends Status case object NotEdited extends Status case class Tweet(content:String, status:Status) 

I want to use the Play Json format, so I think I should have something like this (I don't want to do this in a companion object):

 trait JsonImpl{ implicit val TweetFormat = Json.format[Tweet] implicit val statusFormat = Json.format[Status] implicit val StatusFormat = Json.format[Edited.type] implicit val NotEditedFormat = Json.format[NotEdited.type] } 

but the compiler complains and says:

No implicit format for Tweet available.

He also says that I cannot use Edited.type because it should be applied and not use functions. What should I do?

Edit1:

I can recall something like this:

 implicit object StatusFormat extends Format[Status] { def reads(json: JsValue) = (json \ "type").get.as[String] match { case "" => Edited case _ => UnEdited } def writes(stat: Status) = JsObject(Seq( stat match { case Edited => "type" -> JsString("Edited") case NotEdited => "type" -> JsString("UnEdited") } )) } 

but the read part has a problem, the compiler complains that it needs JsonResult not Edited.type

+7
json scala playframework scala-macros
source share
2 answers

To do this, I must define the implicit object as follows:

  implicit object StatusFormat extends Format[Status] { def reads(json: JsValue) = json match { case JsString("Edited") => JsSuccess(Edited) case JsString("NotEdited") => JsSuccess(NotEdited) case _ => JsError("cannot parse it") } def writes(stat: Status) = JsString(stat.toString) } 
+2
source share

This can also be done quite cleanly with the functional API:

 import play.api.data.validation.ValidationError import play.api.libs.functional.syntax._ import play.api.libs.json._ implicit val StatusFormat: Format[Status] = Format( (__ \ 'type).read[String].collect[Status](ValidationError("Unknown status")) { case "UnEdited" => NotEdited case "Edited" => Edited }, (__ \ 'type).write[String].contramap { case Edited => "Edited" case NotEdited => "UnEdited" } ) implicit val TweetFormat: Format[Tweet] = Json.format[Tweet] 

I find this clearer than using the reads and writes methods manually, mainly because it emphasizes the symmetry between encoding and decoding. However, this is a matter of taste.

+6
source share

All Articles