Reputation: 15385
I have a simple JSON reads and writes using the play json library:
val dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
implicit val jodaDateTimeReads: Reads[DateTime] = Reads[DateTime](js =>
js.validate[String].map[DateTime](dt =>
DateTime.parse(dt, DateTimeFormat.forPattern(dateFormat))
)
)
implicit val jodaDateTimeWrites: Writes[DateTime] = new Writes[DateTime] {
def writes(dt: DateTime): JsValue = JsString(dt.toString())
}
I'm trying to use this DateTime to parse one of my case class which is
case class DefaultMessage(timestamp: DateTime)
I have the corresponding reads and writes in scope and the reads and writes for the DateTime is also in scope:
implicit val defaultMessageReads: Reads[DefaultMessage] = (
(JsPath \ "timestamp").read[DateTime](jodaDateTimeReads)
)(DefaultMessage.apply _)
I get an error that says:
[error] found : org.joda.time.DateTime => com.my.project.messages.DefaultMessage
[error] required: play.api.libs.json.Reads[?]
[error] )(DefaultMessage.apply _)
What does this imply? I thought the signature for the Reads[DefaultMessage] satisfies with the implicit val defaultMessageReads. I can't see what is wrong with this snippet?
Upvotes: 0
Views: 374
Reputation: 2448
There you go.
case class DefaultMessage(timestamp: DateTime)
object DefaultMessage{
val dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
implicit val reads: Reads[DefaultMessage] =
(json: JsValue) => (json \ "timestamp").validate[String]
.map(t => DefaultMessage(DateTime.parse(t, DateTimeFormat.forPattern(dateFormat))))
}
You don't need to change your case class for that, although it makes more sense to have a message in a class called DefaultMessage
:)
Upvotes: 1
Reputation: 15385
It seems to be a crazy issue! Seems like Play Json does not like case classes with a single parameter. I had to change my case class to:
case class DefaultMessage(message: String, timestamp: DateTime)
And then the reads and writes Format sort of works:
implicit val defaultMessageReads: Reads[DefaultMessage] = (
(__ \ "message").read[String] and
(__ \ "timestamp").read[DateTime](jodaDateTimeReads)
)(DefaultMessage.apply _)
implicit val defaultMessageWrites: Writes[DefaultMessage] = (
(JsPath \ "message").write[String] and
(JsPath \ "timestamp").write[DateTime](jodaDateTimeWrites)
)(unlift(DefaultMessage.unapply))
Upvotes: 0