pub fn evaluate(json : Json, path : JSONPath) -> Array[Json] {
let mut current = [json]
for i = 0; i < path.length(); i = i + 1 {
let segment = path[i]
let next = []
for j = 0; j < current.length(); j = j + 1 {
let node = current[j]
match segment {
Root => {
next.push(node)
}
Child(name) => {
match node {
Object(obj) => {
match obj.get(name) {
Some(val) => next.push(val)
None => ()
}
}
_ => ()
}
}
Index(idx) => {
match node {
Array(arr) => {
if idx >= 0 && idx < arr.length() {
next.push(arr[idx])
}
}
_ => ()
}
}
Wildcard => {
match node {
Object(obj) => {
for _, val in obj {
next.push(val)
}
}
Array(arr) => {
for val in arr {
next.push(val)
}
}
_ => ()
}
}
Descendant(name) => {
find_descendants(node, name, next)
}
}
}
current = next
}
current
}
fn find_descendants(node : Json, name : String, acc : Array[Json]) -> Unit {
match node {
Object(obj) => {
match obj.get(name) {
Some(val) => acc.push(val)
None => ()
}
for _, val in obj {
find_descendants(val, name, acc)
}
}
Array(arr) => {
for val in arr {
find_descendants(val, name, acc)
}
}
_ => ()
}
}