proto_types/
cel.rs

1use std::collections::HashMap;
2
3use cel::{objects::Key as CelKey, Value as CelValue};
4use thiserror::Error;
5
6use crate::{Any, DurationError, Empty, FieldMask, TimestampError};
7
8#[derive(Debug, Error)]
9pub enum CelConversionError {
10  #[error("{0}")]
11  DurationError(#[from] DurationError),
12
13  #[error("{0}")]
14  TimestampError(#[from] TimestampError),
15}
16
17impl From<Any> for CelValue {
18  fn from(value: Any) -> Self {
19    let mut cel_map: HashMap<CelKey, CelValue> = HashMap::new();
20    cel_map.insert(
21      "type_url".to_string().into(),
22      CelValue::String(value.type_url.clone().into()),
23    );
24    cel_map.insert(
25      "value".to_string().into(),
26      CelValue::Bytes(value.value.clone().into()),
27    );
28
29    CelValue::Map(cel_map.into())
30  }
31}
32
33#[cfg(feature = "chrono")]
34mod chrono {
35  use cel::Value as CelValue;
36  use chrono::{DateTime, FixedOffset};
37
38  use crate::{cel::CelConversionError, Duration, Timestamp};
39
40  impl TryFrom<Duration> for CelValue {
41    type Error = CelConversionError;
42
43    fn try_from(value: Duration) -> Result<Self, Self::Error> {
44      let chrono_dur: chrono::Duration = value.try_into().map_err(CelConversionError::from)?;
45
46      Ok(CelValue::Duration(chrono_dur))
47    }
48  }
49
50  impl TryFrom<Timestamp> for CelValue {
51    type Error = CelConversionError;
52
53    fn try_from(value: Timestamp) -> Result<Self, Self::Error> {
54      let chrono_timestamp: DateTime<FixedOffset> =
55        value.try_into().map_err(CelConversionError::from)?;
56      Ok(CelValue::Timestamp(chrono_timestamp))
57    }
58  }
59}
60
61impl From<FieldMask> for CelValue {
62  fn from(value: FieldMask) -> Self {
63    let paths = &value.paths;
64
65    let mut cel_vals: Vec<CelValue> = Vec::new();
66    for path in paths {
67      cel_vals.push(CelValue::String(path.clone().into()));
68    }
69
70    let mut cel_map: HashMap<CelKey, CelValue> = HashMap::new();
71    cel_map.insert("paths".into(), CelValue::List(cel_vals.into()));
72
73    CelValue::Map(cel_map.into())
74  }
75}
76
77impl From<&FieldMask> for CelValue {
78  fn from(value: &FieldMask) -> Self {
79    let paths = &value.paths;
80
81    let mut cel_vals: Vec<CelValue> = Vec::new();
82    for path in paths {
83      cel_vals.push(CelValue::String(path.clone().into()));
84    }
85
86    let mut cel_map: HashMap<CelKey, CelValue> = HashMap::new();
87    cel_map.insert("paths".into(), CelValue::List(cel_vals.into()));
88
89    CelValue::Map(cel_map.into())
90  }
91}
92
93impl From<Empty> for CelValue {
94  fn from(_: Empty) -> Self {
95    CelValue::Map(HashMap::<CelKey, CelValue>::new().into())
96  }
97}