Skip to main content

objectiveai_cli/filesystem/
jq.rs

1use jaq_core::{Compiler, Ctx, FilterT, RcIter, load};
2use jaq_json::Val;
3use serde::Serialize;
4
5pub fn run_jq(
6    value: &impl Serialize,
7    filter: &str,
8) -> Result<Vec<serde_json::Value>, super::Error> {
9    let program = load::File {
10        code: filter,
11        path: (),
12    };
13    let loader = load::Loader::new(jaq_std::defs().chain(jaq_json::defs()));
14    let arena = load::Arena::default();
15
16    let modules = loader.load(&arena, program).map_err(|errs| {
17        super::Error::JqParse(
18            errs.into_iter()
19                .map(|e| format!("{e:?}"))
20                .collect::<Vec<_>>()
21                .join(", "),
22        )
23    })?;
24
25    let filter = Compiler::default()
26        .with_funs(jaq_std::funs().chain(jaq_json::funs()))
27        .compile(modules)
28        .map_err(|errs| {
29            super::Error::JqCompile(
30                errs.into_iter()
31                    .map(|e| format!("{e:?}"))
32                    .collect::<Vec<_>>()
33                    .join(", "),
34            )
35        })?;
36
37    let input_value =
38        serde_json::to_value(value).map_err(super::Error::Serialize)?;
39
40    let inputs = RcIter::new(core::iter::empty());
41    let out = filter.run((Ctx::new([], &inputs), Val::from(input_value)));
42
43    let mut results = Vec::new();
44    for item in out {
45        match item {
46            Ok(val) => results.push(serde_json::Value::from(val)),
47            Err(err) => {
48                return Err(super::Error::JqRuntime(format!("{err:?}")));
49            }
50        }
51    }
52    Ok(results)
53}