///|
fn check_access(
input : Value,
tracking : Bool,
span : @ast.Span?,
) -> Unit raise EvalError {
if tracking && input.path is None {
raise EvalError(Json::string("Invalid path expression"), span)
}
}
///|
fn access(
input : Value,
key : Json,
tracking : Bool,
span : @ast.Span?,
) -> Value raise EvalError {
check_access(input, tracking, span)
let found = match path_segment(key) {
Some(segment) => segment.read(input.json)
None => None
}
let json = match found {
Some(json) => json
None =>
raise EvalError(
Json::string(
"Cannot index " +
@ast_internal.json_type_name(input.json) +
" with " +
@ast_internal.json_type_name(key),
),
span,
)
}
{ json, path: input.path.map(p => p + [key]), }
}
///|
fn each(
input : Value,
tracking : Bool,
span : @ast.Span?,
) -> Machine raise EvalError {
check_access(input, tracking, span)
let entries : Iter[(Json, Json)] = match input.json {
Array(arr) => arr.iter().mapi((i, v) => (Json::number(i.to_double()), v))
Object(obj) => obj.iter().map(pair => (Json::string(pair.0), pair.1))
_ =>
raise EvalError(
Json::string(
"Cannot iterate over " + @ast_internal.json_type_name(input.json),
),
span,
)
}
Machine::new(
Values(
entries.map(pair => {
json: pair.1,
path: input.path.map(p => p + [pair.0]),
}),
),
)
}
///|
fn path_result(v : Value, span : @ast.Span?) -> Value raise EvalError {
match v.path {
Some(path) => value(Json::array(path))
None => raise EvalError(Json::string("Invalid path expression"), span)
}
}