Play JSON formatter for Map[Int,_]

后端 未结 6 1409
自闭症患者
自闭症患者 2020-12-29 11:41

I am attempting to migrate a Rails/Mongodb application to Play 2.3 using play-reactivemongo and reactivemongo-extensions. In modeling my data I am running across a problem s

6条回答
  •  无人及你
    2020-12-29 11:59

    Thanks to Seth Tisue. This is my "generics" (half) way.

    "half" because it does not handle a generic key. one can copy paste and replace the "Long" with "Int"

    "Summary" is a type I've wanted to serialize (and it needed its own serializer)

    /** this is how to create reader and writer or format for Maps*/
    //  implicit val mapReads: Reads[Map[Long, Summary]] = new MapLongReads[Summary]
    //  implicit val mapWrites: Writes[Map[Long, Summary]] = new MapLongWrites[Summary]
    implicit val mapLongSummaryFormat: Format[Map[Long, Summary]] = new MapLongFormats[Summary]
    

    This is the required implementation:

    class MapLongReads[T]()(implicit reads: Reads[T]) extends Reads[Map[Long, T]] {
      def reads(jv: JsValue): JsResult[Map[Long, T]] =
        JsSuccess(jv.as[Map[String, T]].map{case (k, v) =>
          k.toString.toLong -> v .asInstanceOf[T]
        })
    }
    
    class MapLongWrites[T]()(implicit writes: Writes[T])  extends Writes[Map[Long, T]] {
      def writes(map: Map[Long, T]): JsValue =
        Json.obj(map.map{case (s, o) =>
          val ret: (String, JsValueWrapper) = s.toString -> Json.toJson(o)
          ret
        }.toSeq:_*)
    }
    
    class MapLongFormats[T]()(implicit format: Format[T]) extends Format[Map[Long, T]]{
      override def reads(json: JsValue): JsResult[Map[Long, T]] = new MapLongReads[T].reads(json)
      override def writes(o: Map[Long, T]): JsValue = new MapLongWrites[T].writes(o)
    }
    

提交回复
热议问题