sqlx_ledger/tx_template/
param_definition.rs1use cel_interpreter::{CelExpression, CelType, CelValue};
2use derive_builder::Builder;
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Debug, Deserialize, Serialize, Builder)]
7#[builder(build_fn(validate = "Self::validate"))]
8pub struct ParamDefinition {
9 #[builder(setter(into))]
10 pub(super) name: String,
11 pub(super) r#type: ParamDataType,
12 #[builder(setter(strip_option, name = "default_expr", into), default)]
13 pub(super) default: Option<String>,
14 #[builder(setter(strip_option, into), default)]
15 pub(super) description: Option<String>,
16}
17
18impl ParamDefinition {
19 pub fn builder() -> ParamDefinitionBuilder {
20 ParamDefinitionBuilder::default()
21 }
22
23 pub fn default_expr(&self) -> Option<CelExpression> {
24 self.default
25 .as_ref()
26 .map(|v| v.parse().expect("Couldn't create default_expr"))
27 }
28}
29
30impl ParamDefinitionBuilder {
31 fn validate(&self) -> Result<(), String> {
32 if let Some(Some(expr)) = self.default.as_ref() {
33 let expr = CelExpression::try_from(expr.as_str()).map_err(|e| e.to_string())?;
34 let param_type = ParamDataType::try_from(
35 &expr
36 .evaluate(&super::cel_context::initialize())
37 .map_err(|e| format!("{e}"))?,
38 )?;
39 let specified_type = self.r#type.as_ref().unwrap();
40 if ¶m_type != specified_type {
41 return Err(format!(
42 "Default expression type {param_type:?} does not match parameter type {specified_type:?}"
43 ));
44 }
45 }
46 Ok(())
47 }
48}
49
50#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
51pub enum ParamDataType {
52 STRING,
53 INTEGER,
54 DECIMAL,
55 BOOLEAN,
56 UUID,
57 DATE,
58 TIMESTAMP,
59 JSON,
60}
61
62impl TryFrom<&CelValue> for ParamDataType {
63 type Error = String;
64
65 fn try_from(value: &CelValue) -> Result<Self, Self::Error> {
66 use cel_interpreter::CelType::*;
67 match CelType::from(value) {
68 Int => Ok(ParamDataType::INTEGER),
69 String => Ok(ParamDataType::STRING),
70 Map => Ok(ParamDataType::JSON),
71 Date => Ok(ParamDataType::DATE),
72 Uuid => Ok(ParamDataType::UUID),
73 Decimal => Ok(ParamDataType::DECIMAL),
74 Bool => Ok(ParamDataType::BOOLEAN),
75 _ => Err(format!("Unsupported type: {value:?}")),
76 }
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn build_param_definition() {
86 let definition = ParamDefinition::builder()
87 .name("name")
88 .r#type(ParamDataType::JSON)
89 .default_expr("{'key': 'value'}")
90 .build()
91 .unwrap();
92 assert_eq!(definition.name, "name");
93 }
94}