Last active
August 29, 2015 14:02
-
-
Save sadache/d357ced8f6c942bca81a to your computer and use it in GitHub Desktop.
Faster with much less memory consumption JSON object reader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def objectReader[T1,T2,T3,T4,R](t1: String, t2: String, t3: String, t4: String)(f: (T1,T2,T3,T4) => R)(implicit readsT1:Reads[T1], readsT2:Reads[T2], readsT3:Reads[T3], readsT4:Reads[T4]): Reads[R] = { | |
def orElse[A](a:A, default: =>A) = if(a!=null) a else default | |
Reads[R]{ | |
case JsObject(fields) => | |
var t1V:JsResult[T1] = null.asInstanceOf[JsResult[T1]] | |
var t2V:JsResult[T2] = null.asInstanceOf[JsResult[T2]] | |
var t3V:JsResult[T3] = null.asInstanceOf[JsResult[T3]] | |
var t4V:JsResult[T4] = null.asInstanceOf[JsResult[T4]] | |
var els = fields.toIterator | |
while((els.hasNext) && (t1V == null || t2V == null || t3V == null || t4V == null)){ | |
val (key, value) = els.next() | |
key match { | |
case `t1` => t1V = readsT1.reads(value) | |
case `t2` => t2V = readsT2.reads(value) | |
case `t3` => t3V = readsT3.reads(value) | |
case `t4` => t4V = readsT4.reads(value) | |
case _ => // | |
} | |
} | |
(t1V, t2V, t3V, t4V) match { | |
case (JsSuccess(tt1, _), JsSuccess(tt2, _), JsSuccess(tt3, _), JsSuccess(tt4, _)) => | |
JsSuccess(f(tt1, tt2, tt3, tt4)) | |
case _ => | |
List( | |
orElse(t1V, JsError(Seq((JsPath.\(t1), Seq(ValidationError("error.path.missing")))))), | |
orElse(t2V, JsError(Seq((JsPath.\(t2), Seq(ValidationError("error.path.missing")))))), | |
orElse(t3V, JsError(Seq((JsPath.\(t3), Seq(ValidationError("error.path.missing")))))), | |
orElse(t4V, JsError(Seq((JsPath.\(t4), Seq(ValidationError("error.path.missing")))))) | |
).collect { case e: JsError => e }.reduceLeft(_.++(_)) | |
} | |
case js => JsError(Seq(JsPath() -> Seq(ValidationError("error.expected.jsobject")))) | |
} | |
} |
It used to be so, except you'd loose the original order of fields :)
I know. There's no "good" solution :(
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Good point. I'm not a big fan of the solution though, as you may have expected ;)
A definition of
JsObject
along the line ofcase class JsObject(fields: Map[String, JsValue])
would be much more appropriate in your case.