use delegate::delegate; use derivative::Derivative; use derive_more::{Deref, DerefMut, From, IntoIterator}; use prost::Message; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; /// Generates a stable digest strictly within the lifecycle of the current process. /// /// ⚠️ WARNING: /// - This digest is ONLY guaranteed to be deterministic within a **single process and the exact same binary build**. pub trait TransientDigest: Message { fn digest(&self) -> [u8; 32] where Self: Sized, { let buf = self.encode_to_vec(); let mut hasher = Sha256::new(); hasher.update(buf); hasher.finalize().into() } } impl TransientDigest for S {} 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( Derivative, Debug, Clone, PartialEq, Eq, Hash, From, Deref, DerefMut, Serialize, Deserialize, IntoIterator, )] #[derivative(Default(bound = ""))] #[serde(transparent)] #[into_iterator(owned, ref, ref_mut)] pub struct RepeatedMessageModel(Vec); impl RepeatedMessageModel { pub fn into_inner(self) -> Vec { self.0 } } impl FromIterator for RepeatedMessageModel { fn from_iter>(iter: I) -> Self { Self(iter.into_iter().collect()) } } impl Extend for RepeatedMessageModel { delegate! { to self.0 { fn extend>(&mut self, iter: T); } } } impl AsRef<[Model]> for RepeatedMessageModel { delegate! { to self.0 { fn as_ref(&self) -> &[Model]; } } } impl AsMut<[Model]> for RepeatedMessageModel { delegate! { to self.0 { fn as_mut(&mut self) -> &mut [Model]; } } } impl<'m, Message, Model> TryFrom<&'m [Message]> for RepeatedMessageModel where Message: prost::Message, Model: MessageModel, { type Error = >::Error; fn try_from(value: &'m [Message]) -> Result { value.iter().map(TryInto::try_into).collect() } } impl From> for Vec where Message: prost::Message, Model: MessageModel, { fn from(value: RepeatedMessageModel) -> Self { value.into_iter().map(Into::into).collect() } }