Skip to main content

cala_ledger/param/
mod.rs

1pub mod definition;
2pub mod error;
3
4use cel_interpreter::{CelContext, CelMap, CelValue};
5use es_entity::clock::ClockHandle;
6use std::collections::HashMap;
7use tracing::instrument;
8
9pub use cala_types::param::*;
10
11use error::*;
12
13#[derive(Clone, Debug)]
14pub struct Params {
15    values: HashMap<String, CelValue>,
16}
17
18impl Params {
19    pub fn new() -> Self {
20        Self {
21            values: HashMap::new(),
22        }
23    }
24
25    pub fn insert(&mut self, k: impl Into<String>, v: impl Into<CelValue>) {
26        self.values.insert(k.into(), v.into());
27    }
28
29    #[instrument(name = "params.into_context", skip(self, clock, defs), fields(params_count = self.values.len()), err)]
30    pub(crate) fn into_context(
31        mut self,
32        clock: &ClockHandle,
33        defs: Option<&Vec<ParamDefinition>>,
34    ) -> Result<CelContext, ParamError> {
35        let mut ctx = crate::cel_context::initialize(clock.clone());
36        if let Some(defs) = defs {
37            let mut cel_map = CelMap::new();
38            for d in defs {
39                if let Some(v) = self.values.remove(&d.name) {
40                    cel_map.insert(
41                        d.name.clone(),
42                        d.r#type
43                            .coerce_value(v)
44                            .map_err(ParamError::ParamTypeMismatch)?,
45                    );
46                } else if let Some(expr) = d.default.as_ref() {
47                    cel_map.insert(d.name.clone(), expr.evaluate(&ctx)?);
48                }
49            }
50            ctx.add_variable("params", cel_map);
51        }
52
53        Ok(ctx)
54    }
55}
56
57impl Default for Params {
58    fn default() -> Self {
59        Self::new()
60    }
61}