Skip to main content

cala_ledger/param/
definition.rs

1use derive_builder::Builder;
2use serde::{Deserialize, Serialize};
3
4pub use cala_types::param::*;
5use cel_interpreter::CelExpression;
6
7#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
8#[builder(build_fn(validate = "Self::validate"))]
9pub struct NewParamDefinition {
10    #[builder(setter(into))]
11    pub(crate) name: String,
12    pub(crate) r#type: ParamDataType,
13    #[builder(setter(strip_option, name = "default_expr", into), default)]
14    pub(crate) default: Option<String>,
15    #[builder(setter(strip_option, into), default)]
16    pub(crate) description: Option<String>,
17}
18
19impl NewParamDefinition {
20    pub fn builder() -> NewParamDefinitionBuilder {
21        NewParamDefinitionBuilder::default()
22    }
23
24    pub fn default_expr(&self) -> Option<CelExpression> {
25        self.default
26            .as_ref()
27            .map(|v| v.parse().expect("Couldn't create default_expr"))
28    }
29}
30
31impl NewParamDefinitionBuilder {
32    fn validate(&self) -> Result<(), String> {
33        use es_entity::clock::Clock;
34        if let Some(Some(expr)) = self.default.as_ref() {
35            let expr = CelExpression::try_from(expr.as_str()).map_err(|e| e.to_string())?;
36            let param_type = ParamDataType::try_from(
37                &expr
38                    .evaluate(&crate::cel_context::initialize(Clock::handle().clone()))
39                    .map_err(|e| format!("{e}"))?,
40            )?;
41            let specified_type = self.r#type.as_ref().unwrap();
42            if &param_type != specified_type {
43                return Err(format!(
44                    "Default expression type {param_type:?} does not match parameter type {specified_type:?}"
45                ));
46            }
47        }
48        Ok(())
49    }
50}
51
52impl From<NewParamDefinition> for cala_types::tx_template::ParamDefinition {
53    fn from(param: NewParamDefinition) -> Self {
54        let default = param.default_expr();
55        cala_types::tx_template::ParamDefinition {
56            name: param.name,
57            r#type: param.r#type,
58            default,
59            description: param.description,
60        }
61    }
62}
63#[cfg(test)]
64mod tests {
65    use super::*;
66
67    #[test]
68    fn build_param_definition() {
69        let definition = NewParamDefinition::builder()
70            .name("name")
71            .r#type(ParamDataType::Json)
72            .default_expr("{'key': 'value'}")
73            .build()
74            .unwrap();
75        assert_eq!(definition.name, "name");
76    }
77}