This commit is contained in:
Wölfchen 2024-09-26 15:23:07 -04:00 committed by GitHub
commit 43bf6cd0c8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -457,6 +457,8 @@ fn call_expr_function(name: &str, args: Vec<DynVal>) -> Result<DynVal, EvalError
"jq" => match args.as_slice() {
[json, code] => run_jaq_function(json.as_json_value()?, code.as_string()?)
.map_err(|e| EvalError::Spanned(code.span(), Box::new(e))),
[json, code, args] => run_jaq_with_args(json.as_json_value()?, code.as_string()?, &args.as_string()?)
.map_err(|e| EvalError::Spanned(code.span(), Box::new(e))),
_ => Err(EvalError::WrongArgCount(name.to_string())),
},
"formattime" => match args.as_slice() {
@ -505,16 +507,29 @@ fn prepare_jaq_filter(code: String) -> Result<Arc<jaq_interpret::Filter>, EvalEr
Ok(Arc::new(filter))
}
/// duplication for a slight performance increase
fn run_jaq_with_args(json: serde_json::Value, code: String, args: &str) -> Result<DynVal, EvalError> {
prepare_jaq_filter(code)?
.run((jaq_interpret::Ctx::new([], &jaq_interpret::RcIter::new(std::iter::empty())), jaq_interpret::Val::from(json)))
.map(|r| r.map(Into::<serde_json::Value>::into))
.map(|x| {
x.map(|val| match (args, val) {
("r", serde_json::Value::String(s)) => DynVal::from_string(s),
// silently ignore invalid args
(_, v) => DynVal::from_string(serde_json::to_string(&v).unwrap()),
})
})
.collect::<Result<DynVal, _>>()
.map_err(|e| EvalError::JaqError(e.to_string()))
}
fn run_jaq_function(json: serde_json::Value, code: String) -> Result<DynVal, EvalError> {
let filter: Arc<jaq_interpret::Filter> = prepare_jaq_filter(code)?;
let inputs = jaq_interpret::RcIter::new(std::iter::empty());
let out = filter
.run((jaq_interpret::Ctx::new([], &inputs), jaq_interpret::Val::from(json)))
.map(|x| x.map(Into::<serde_json::Value>::into))
prepare_jaq_filter(code)?
.run((jaq_interpret::Ctx::new([], &jaq_interpret::RcIter::new(std::iter::empty())), jaq_interpret::Val::from(json)))
.map(|r| r.map(Into::<serde_json::Value>::into))
.map(|x| x.map(|x| DynVal::from_string(serde_json::to_string(&x).unwrap())))
.collect::<Result<_, _>>()
.map_err(|e| EvalError::JaqError(e.to_string()))?;
Ok(out)
.map_err(|e| EvalError::JaqError(e.to_string()))
}
#[cfg(test)]
@ -573,5 +588,9 @@ mod tests {
lazy_evaluation_or(r#"true || "null".test"#) => Ok(DynVal::from(true)),
lazy_evaluation_elvis(r#""test"?: "null".test"#) => Ok(DynVal::from("test")),
jq_basic_index(r#"jq("[7,8,9]", ".[0]")"#) => Ok(DynVal::from(7)),
jq_raw_arg(r#"jq("[ \"foo\" ]", ".[0]", "r")"#) => Ok(DynVal::from("foo")),
jq_empty_arg(r#"jq("[ \"foo\" ]", ".[0]", "")"#) => Ok(DynVal::from(r#""foo""#)),
jq_invalid_arg(r#"jq("[ \"foo\" ]", ".[0]", "hello")"#) => Ok(DynVal::from(r#""foo""#)),
jq_no_arg(r#"jq("[ \"foo\" ]", ".[0]")"#) => Ok(DynVal::from(r#""foo""#)),
}
}