use crate::errors::{DispatchError, InternalError}; use bytes::Bytes; // To bytes pub trait ToBytes { fn into_bytes(self) -> Result; } #[cfg(feature = "use_protobuf")] impl ToBytes for T where T: std::convert::TryInto, { fn into_bytes(self) -> Result { match self.try_into() { Ok(data) => Ok(data), Err(e) => Err(InternalError::ProtobufError(format!("{:?}", e)).into()), } } } #[cfg(feature = "use_serde")] impl ToBytes for T where T: serde::Serialize, { fn into_bytes(self) -> Result { match serde_json::to_string(&self.0) { Ok(s) => Ok(Bytes::from(s)), Err(e) => Err(InternalError::SerializeToBytes(format!("{:?}", e)).into()), } } } // From bytes pub trait FromBytes: Sized { fn parse_from_bytes(bytes: Bytes) -> Result; } #[cfg(feature = "use_protobuf")] impl FromBytes for T where // // https://stackoverflow.com/questions/62871045/tryfromu8-trait-bound-in-trait // T: for<'a> std::convert::TryFrom<&'a Bytes, Error = // protobuf::ProtobufError>, T: std::convert::TryFrom, { fn parse_from_bytes(bytes: Bytes) -> Result { match T::try_from(bytes) { Ok(data) => Ok(data), Err(e) => { tracing::error!( "Parse payload to {} failed with error: {:?}", std::any::type_name::(), e ); Err(e.into()) } } } } #[cfg(feature = "use_serde")] impl FromBytes for T where T: serde::de::DeserializeOwned + 'static, { fn parse_from_bytes(bytes: Bytes) -> Result { let s = String::from_utf8_lossy(&bytes); match serde_json::from_str::(s.as_ref()) { Ok(data) => Ok(data), Err(e) => Err(format!("{:?}", e)), } } }