Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package lib
- import play.api.libs.json._
- import Json._
- import scala.annotation.implicitNotFound
- import play.api.data.validation.ValidationError
- import scala.collection.mutable.LinkedHashMap
- trait CustomReads {
- /**
- * Deserializer for LinkedHashMap[String,V] types.
- */
- implicit def linkedHashMapReads[V](implicit fmtv: Reads[V]): Reads[scala.collection.mutable.LinkedHashMap[String, V]] = new Reads[scala.collection.mutable.LinkedHashMap[String, V]] {
- def reads(json: JsValue) = json match {
- case JsObject(m) => {
- // first validates prod separates JsError / JsResult in an Seq[Either( (key, errors, globals), (key, v, jselt) )]
- // the aim is to find all errors prod then to merge them all
- var hasErrors = false
- val r = m.map {
- case (key, value) =>
- fromJson[V](value)(fmtv) match {
- case JsSuccess(v, _) => Right((key, v, value))
- case JsError(e) =>
- hasErrors = true
- Left(e.map { case (p, valerr) => (JsPath \ key) ++ p -> valerr })
- }
- }
- // if errors, tries to merge them into a single JsError
- if (hasErrors) {
- val fulle = r.filter(_.isLeft).map(_.left.get)
- .foldLeft(List[(JsPath, Seq[ValidationError])]())((acc, v) => acc ++ v)
- JsError(fulle)
- } // no error, rebuilds the map
- else JsSuccess(r.filter(_.isRight).map(_.right.get).map { v => v._1 -> v._2 }.toMap.asInstanceOf[scala.collection.mutable.LinkedHashMap[String,V]])
- }
- case _ => JsError(Seq(JsPath() -> Seq(ValidationError("error.expected.jsobject"))))
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement