proto_types/
cel.rs

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