///|
fn lookup(name : String, context : Context) -> Json? {
if name != "." && name.contains(".") {
let parts = name.split(".")
return parts
.head()
.bind(head => lookup(head.to_string(), context).bind(value => {
let tail = parts[1:].map(s => s.to_string()).join(".")
lookup(tail, Context([value]))
}))
}
for c in context.0 {
if name == "." {
return Some(c)
}
let value = match c {
Object(obj) => obj.get(name)
_ => Some(c)
}
if value is Some(_) {
return value
}
}
return None
}
///|
fn is_falsy(value : Json) -> Bool {
match value {
Null => true
False => true
String(s) => s.length() == 0
Array(a) => a.length() == 0
Object(_) => false
Number(n, ..) => n == 0.0
True => false
}
}
///|
test {
let ctx = Context([
{ "a": Json::number(2), "b": Json::object({ "c": Json::string("text") }) },
{ "e": Json::object({ "f": Json::object({ "g": Json::boolean(true) }) }) },
])
let retrived = [
(lookup("a", ctx), Json::number(2)),
(lookup("b.c", ctx), Json::string("text")),
(lookup("e.f.g", ctx), Json::boolean(true)),
]
for value in retrived {
assert_eq(value.0, Some(value.1))
}
}