amnaredo / test

0 stars 0 forks source link

Creating a custom pickler for a Java class (ZonedDateTime) #246

Open amnaredo opened 2 years ago

amnaredo commented 2 years ago

Recently I needed to create a custom pickler for the Java class ZonedDateTime. I had some trouble with this due to my vague understanding of implicit resolution, but ended up making it work with the following:

object ZonedDateTimeRW {
  val formatter = DateTimeFormatter.ISO_INSTANT

  implicit def rw: JsonPickler.ReadWriter[ZonedDateTime] = JsonPickler.readwriter[String].bimap[ZonedDateTime](
    zonedDateTime => formatter.format(zonedDateTime),
    str => ZonedDateTime.parse(str, formatter))
}

object MyCaseClassWithZonedDateTimeInIt {
  implicit val zonedDateTimeRW = ZonedDateTimeRW.rw
  implicit def rw: JsonPickler.ReadWriter[MyCaseClassWithZonedDateTimeInIt] = JsonPickler.macroRW
}

Just posting here so others can find this when searching. ID: 260 Original Author: RyanSattler

amnaredo commented 2 years ago

Thanks for posting this :) This is my version with improved implicit resolution. Implicit ReadWriter instances should be defined as implicit val and your ReadWriter[ZonedDateTime] should be imported after upickle.default._ in case you need a more specialized ReadWriter with ZonedDateTime, e.g. ReadWriter[Option[ZonedDateTime]].

ZonedDateTimeRW.scala:

object ZonedDateTimeRW {
  import upickle.default._

  val formatter = DateTimeFormatter.ISO_INSTANT

  implicit val rw: ReadWriter[ZonedDateTime] = readwriter[String].bimap[ZonedDateTime](
    zonedDateTime => formatter.format(zonedDateTime),
    str => ZonedDateTime.parse(str, formatter))
}

MyCaseClassWithZonedDateTimeInit.scala:

object MyCaseClassWithZonedDateTimeInIt {
  import upickle.default._
  import ZonedDateTimeRw._

  implicit val rw: ReadWriter[MyCaseClassWithZonedDateTimeInIt] = macroRW
}

Original Author: skirsdeda