1use std::io;
2use std::io::BufRead;
3
4use serde_json::{Map, Value, json};
5
6use cel::{Context, Program};
7
8pub struct CelValue(pub cel::Value);
9
10impl From<CelValue> for serde_json::Value {
11 fn from(wrapper_cel_value: CelValue) -> Self {
12 let cel_value = wrapper_cel_value.0;
13 match cel_value {
14 cel::Value::Null => serde_json::Value::Null,
15 cel::Value::Bool(b) => serde_json::Value::Bool(b),
16 cel::Value::Int(i) => json!(i),
17 cel::Value::UInt(u) => json!(u),
18 cel::Value::Float(f) => json!(f),
19 cel::Value::String(s) => serde_json::Value::String(s.to_string()),
20 cel::Value::List(list) => {
21 let values: &[cel::Value] = &list;
22 serde_json::Value::Array(
23 values.iter().map(|v| CelValue(v.clone()).into()).collect(),
24 )
25 }
26 cel::Value::Map(map_obj) => {
27 let mut json_map = Map::new();
28 for (key, val) in map_obj.map.iter() {
29 let cel_key_value: cel::Value = key.into(); let key_str = match cel_key_value {
33 cel::Value::String(s) => s.to_string(),
34 _ => format!("{:?}", cel_key_value), };
36 json_map.insert(key_str, CelValue(val.clone()).into());
37 }
38 serde_json::Value::Object(json_map)
39 }
40 _ => serde_json::Value::String(format!("{:?}", cel_value)),
41 }
42 }
43}
44
45pub struct CelProgram(pub Program);
46
47impl CelProgram {
48 pub fn execute(&self, ctx: &Context) -> Result<cel::Value, io::Error> {
49 self.0.execute(ctx).map_err(io::Error::other)
50 }
51
52 pub fn execute_with_value(
53 &self,
54 ctx: &Context,
55 vname: &str,
56 val: Value,
57 ) -> Result<cel::Value, io::Error> {
58 let mut child: Context = ctx.new_inner_scope();
59 child.add_variable(vname, val).map_err(io::Error::other)?;
60 self.execute(&child)
61 }
62
63 pub fn jsons2mapped<I>(
64 self,
65 jsons: I,
66 ctx: Context,
67 vname: String,
68 ) -> impl Iterator<Item = Result<Value, io::Error>>
69 where
70 I: Iterator<Item = Result<Value, io::Error>>,
71 {
72 jsons.map(move |rv| match rv {
73 Ok(v) => {
74 let mapped_cel_value = self.execute_with_value(&ctx, &vname, v)?;
75 Ok(CelValue(mapped_cel_value).into())
76 }
77 Err(e) => Err(e),
78 })
79 }
80}
81
82pub fn compile(expr: &str) -> Result<CelProgram, io::Error> {
83 Program::compile(expr)
84 .map(CelProgram)
85 .map_err(io::Error::other)
86}
87
88pub fn rdr2jsons<R>(rdr: R) -> impl Iterator<Item = Result<Value, io::Error>>
89where
90 R: BufRead,
91{
92 rdr.lines()
93 .map(|rline| rline.and_then(|line| serde_json::from_str(&line).map_err(io::Error::other)))
94}
95
96pub fn stdin2jsons() -> impl Iterator<Item = Result<Value, io::Error>> {
97 rdr2jsons(io::stdin().lock())
98}