
net.uniscala.json.JsonPath.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of uniscala-json_2.10 Show documentation
Show all versions of uniscala-json_2.10 Show documentation
A compact JSON library written in Scala.
The newest version!
/**
* This file is part of the Uniscala JSON project.
* Copyright (C) 2012 Sustainable Software Pty Ltd.
* This is open source software, licensed under the Apache License
* version 2.0 license - please see the LICENSE file included in
* the distribution.
*
* Authors:
* Sam Stainsby ([email protected])
*/
package net.uniscala.json
import scala.annotation.tailrec
import scala.collection.SeqProxy
object JsonPath {
val root = new JsonPath()
lazy val / = root
implicit def wrapStringIntoPath(s: String) = new JsonPath(s)
}
/**
* A path into a hierarchy of JSON objects specified as a sequence of
* keys.
*/
case class JsonPath(segments: String*) extends SeqProxy[String] {
override val self = segments
/**
* Appends path segments to this path.
*/
def /(segments: String*): JsonPath = {
new JsonPath((this.segments ++ segments):_*)
}
private def filterByClass[J <: JsonValue[_] : Manifest](subjson: JsonValue[_]): Option[J] = {
val targetClass: Class[_] = manifest[J].erasure
val foundClass = subjson.getClass
if (targetClass.isAssignableFrom(foundClass)) {
Some(subjson.asInstanceOf[J])
} else {
None
}
}
/**
* Applies a function to the value, if any, that this path points to in
* the supplied JSON object. If the path is invalid, that is, if it
* doesn't point to a value, or if the type pointed to is not assignable
* to J, then None is returned. Otherwise the result of applying the
* function is returned, wrapped in Some.
*/
def at[J <: JsonValue[_] : Manifest, T](
jobj: JsonObject,
f: J=>T
): Option[T] = {
@tailrec def at_(
json: JsonValue[_],
segs: String*
): Option[T] = {
json match {
case jobj: JsonObject => {
jobj.get(segs.head) match {
case None => None
case Some(subjson) => {
if (segs.size == 1) {
filterByClass[J](subjson).map(f(_))
} else {
at_(subjson, segs.tail:_*)
}
}
}
}
case _ => None
}
}
if (this.isEmpty) {
filterByClass[J](jobj).map(f(_))
} else {
at_(jobj, segments:_*)
}
}
override def toString() = this mkString ":"
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy