Skip to content

Instantly share code, notes, and snippets.

@jroper
Created October 17, 2013 04:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jroper/7019306 to your computer and use it in GitHub Desktop.
Save jroper/7019306 to your computer and use it in GitHub Desktop.
Reads for recursive search paths
// Reads for recursive path
def recursiveSearchReads[T : Reads](path: JsPath) = Reads[Seq[T]] { json =>
path.apply(json).map(_.validate[T]).foldLeft[JsResult[Seq[T]]](JsSuccess(Nil)) {
case (JsError(a), JsError(b)) => JsError(a ++ b)
case (err: JsError, _) => err
case (_, err: JsError) => err
case (JsSuccess(ts, _), JsSuccess(t, _)) => JsSuccess(ts :+ t)
}.repath(path)
}
// Reads for recursive path of arrays, flattened
def recursiveSearchReadsFlatten[T : Reads](path: JsPath) = Reads[Seq[T]] { json =>
path.apply(json).map(_.validate[Seq[T]]).reduceLeft[JsResult[Seq[T]]] {
case (JsError(a), JsError(b)) => JsError(a ++ b)
case (err: JsError, _) => err
case (_, err: JsError) => err
case (JsSuccess(a, _), JsSuccess(b, _)) => JsSuccess(a ++ b)
}.repath(path)
}
@jroper
Copy link
Author

jroper commented Oct 17, 2013

Reads for recursive paths... perhaps we should add these methods to JsPath, currently, you can't:

(__ \\ "foo").read[Seq[Foo]]

But with this you can:

recursiveSearchReads[Foo](__ \\ "foo")

Something else that would be good is a simple way to Seq[JsResult[T]] => JsResult[Seq[T]], in case the above was not powerful enough for you, you could use that method to implement the above in far less code.

@mandubian
Copy link

Actually we don't have it because nobody asked for it IMHO :D

The equivalent of Future.sequence for JsResult would be cool too.
I thought I had written it somewhere but I don't find it anymore!

I also believe some Reads based on JsZipper would be far more powerful...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment