Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a Json Reads Combinator for a Map[Int, Long]

I am trying to write a json reads combinator for type Map[Int, Long]

I have this so far:

implicit val mapWrites = Json.writes[Map[Int, Long]]

implicit val mapReads: Reads[Map[Int, Long]] = (
  // ???
) // ?

I'm not sure how this will work, I tried doing (Map[Int, Long].apply but that apply method was not available.

Looking for some help to write this Reads combinator.

like image 260
Blankman Avatar asked Feb 23 '15 15:02

Blankman


1 Answers

This should do it, with the caveat that it doesn't handle NumberFormatException in the reads case:

//
// scala> Json.toJson(Map(1 -> 2L, 2 -> 3L))
// res0: play.api.libs.json.JsValue = {"1":2,"2":3}
//
implicit val formatter: Format[Map[Int, Long]] = {
  new Format[Map[Int, Long]] {
    def writes(m: Map[Int, Long]) = {
      Json.toJson(m.map {
        case (key, value) => key.toString -> value
      })
    }

    def reads(json: JsValue) = {
      json.validate[Map[String, Long]].map(_.map {
        case (key, value) => key.toInt -> value
      })
    }
  }
}

As separate Reads and Writes instances:

implicit val readsInstance: Reads[Map[Int, Long]] = {
  new Reads[Map[Int, Long]] {
    def reads(json: JsValue) = {
      json.validate[Map[String, Long]].map(_.map {
        case (key, value) => key.toInt -> value
      })
    }
  }
}

implicit val writesInstance: Writes[Map[Int, Long]] = {
    def writes(m: Map[Int, Long]) = {
      Json.toJson(m.map {
        case (key, value) => key.toString -> value
      })
    }
  }
}
like image 78
Ionuț G. Stan Avatar answered Nov 06 '22 18:11

Ionuț G. Stan