diff --git a/easytier/src/proto/mod.rs b/easytier/src/proto/mod.rs index 63363c3f..02d69bd6 100644 --- a/easytier/src/proto/mod.rs +++ b/easytier/src/proto/mod.rs @@ -14,6 +14,7 @@ pub mod web; #[cfg(test)] pub mod tests; +pub mod utils; const DESCRIPTOR_POOL_BYTES: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/file_descriptor_set.bin")); diff --git a/easytier/src/proto/utils.rs b/easytier/src/proto/utils.rs new file mode 100644 index 00000000..80fde761 --- /dev/null +++ b/easytier/src/proto/utils.rs @@ -0,0 +1,49 @@ +use derive_more::{Deref, DerefMut, From, IntoIterator}; +use itertools::Itertools; +use serde::{Deserialize, Serialize}; +use crate::dns::utils::MapTryInto; + +pub trait MessageModel: Into + for<'m> TryFrom<&'m Message> {} + +impl MessageModel for Model +where + Message: prost::Message, + Model: Into + for<'m> TryFrom<&'m Message>, +{ +} + +#[derive( + Debug, Clone, PartialEq, Eq, Hash, From, Deref, DerefMut, Serialize, Deserialize, IntoIterator, +)] +#[serde(transparent)] +#[into_iterator(owned, ref, ref_mut)] +pub struct RepeatedMessageModel(Vec); + +impl Default for RepeatedMessageModel +{ + fn default() -> Self { + Self(vec![]) + } +} + +impl<'m, Message, Model> TryFrom<&'m Vec> for RepeatedMessageModel +where + Message: prost::Message, + Model: MessageModel, +{ + type Error = >::Error; + + fn try_from(value: &'m Vec) -> Result { + Ok(Self(value.map_try_into().collect::, _>>()?)) + } +} + +impl From> for Vec +where + Message: prost::Message, + Model: MessageModel, +{ + fn from(value: RepeatedMessageModel) -> Self { + value.into_iter().map_into().collect() + } +}