Skip to main content

proto_types/
cel.rs

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