irongit
jv/src/jq_engine.rs
69 lines1.9 KBRust
1use jaq_interpret::{Ctx, FilterT, ParseCtx, RcIter, Val};
2
3pub struct JqEngine;
4
5#[derive(Debug)]
6pub struct JqResult {
7 pub output: Vec<String>,
8 pub error: Option<String>,
9}
10
11impl JqEngine {
12 pub fn execute(query: &str, input: &serde_json::Value) -> JqResult {
13 if query.trim().is_empty() {
14 return JqResult {
15 output: vec![serde_json::to_string_pretty(input).unwrap_or_default()],
16 error: None,
17 };
18 }
19
20 let mut defs = ParseCtx::new(Vec::new());
21 defs.insert_natives(jaq_core::core());
22 defs.insert_defs(jaq_std::std());
23
24 let (filter, errs) = jaq_parse::parse(query, jaq_parse::main());
25
26 if !errs.is_empty() {
27 return JqResult {
28 output: Vec::new(),
29 error: Some(format!("Parse error in query")),
30 };
31 }
32
33 let Some(filter) = filter else {
34 return JqResult {
35 output: Vec::new(),
36 error: Some("Failed to parse query".to_string()),
37 };
38 };
39
40 let filter = defs.compile(filter);
41
42 let inputs = RcIter::new(core::iter::empty());
43 let val = Val::from(input.clone());
44
45 let mut output = Vec::new();
46 for result in filter.run((Ctx::new([], &inputs), val)) {
47 match result {
48 Ok(v) => {
49 let json_val: serde_json::Value = v.into();
50 output.push(
51 serde_json::to_string_pretty(&json_val)
52 .unwrap_or_else(|_| format!("{:?}", json_val)),
53 );
54 }
55 Err(e) => {
56 return JqResult {
57 output,
58 error: Some(format!("{}", e)),
59 };
60 }
61 }
62 }
63
64 JqResult {
65 output,
66 error: None,
67 }
68 }
69}