Skip to content

Instantly share code, notes, and snippets.

@julienrf
Created December 3, 2011 15:08
Show Gist options
  • Save julienrf/1427338 to your computer and use it in GitHub Desktop.
Save julienrf/1427338 to your computer and use it in GitHub Desktop.
Querying JSON
package jsonquery
object `package` {
import dispatch.json._
implicit def jsonToSearchable(json: JsValue) = new {
def \ (selector: String): Either[String, JsValue] = json match {
case JsObject(map) => {
(for {
value <- map.get(JsString(selector))
} yield {
Right(value)
}) getOrElse Left("'%s' is undefined on object: %s".format(selector, json))
}
case _ => Left("'%s' is undefined on object: %s".format(selector, json))
}
}
implicit def eitherToSearchable(e: Either[String, JsValue]) = new {
def \ (selector: String): Either[String, JsValue] = {
for {
json <- e.right
result <- (json \ selector).right
} yield result
}
}
}
package jsonquery
import org.specs2.mutable._
import dispatch.json._
class SJsonQuerySpec extends Specification {
val json = JsObject(List(
JsString("foo")->JsString("bar"),
JsString("baz")->JsNumber(42),
JsString("bah")->JsObject(List(
JsString("nested")->JsNumber(1)
))
))
val jsonArray = new JsArray(List(
JsObject(List(JsString("foo")->JsString("bar"))),
JsObject(List(JsString("foo")->JsString("baz")))
))
"sjson-query" should {
"find a value from an object and its key" >> {
(json \ "foo").right.get must be_== (JsString("bar"))
(for {
JsString(value) <- (json \ "foo").right.toOption
} yield {
value
}).get must be_== ("bar")
}
"return an error on unsuccessful search" >> {
(json \ "bar").isLeft must beTrue
}
"allow to search consecutively" >> {
(json \ "bah" \ "nested").right.get must be_== (JsNumber(1))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment