use std::fmt::{Debug, Formatter}; use std::ops; use bytes::Bytes; use validator::ValidationErrors; use crate::{ byte_trait::*, errors::{DispatchError, InternalError}, request::{unexpected_none_payload, AFPluginEventRequest, FromAFPluginRequest, Payload}, response::{AFPluginEventResponse, AFPluginResponder, ResponseBuilder}, util::ready::{ready, Ready}, }; pub trait AFPluginDataValidator { fn validate(self) -> Result where Self: Sized; } pub struct AFPluginData(pub T); impl AFPluginData { pub fn into_inner(self) -> T { self.0 } } impl ops::Deref for AFPluginData { type Target = T; fn deref(&self) -> &T { &self.0 } } impl AFPluginDataValidator for AFPluginData where T: validator::Validate, { fn validate(self) -> Result { self.0.validate()?; Ok(self) } } impl ops::DerefMut for AFPluginData { fn deref_mut(&mut self) -> &mut T { &mut self.0 } } impl FromAFPluginRequest for AFPluginData where T: AFPluginFromBytes + 'static, { type Error = DispatchError; type Future = Ready>; #[inline] fn from_request(req: &AFPluginEventRequest, payload: &mut Payload) -> Self::Future { match payload { Payload::None => ready(Err(unexpected_none_payload(req))), Payload::Bytes(bytes) => match T::parse_from_bytes(bytes.clone()) { Ok(data) => ready(Ok(AFPluginData(data))), Err(e) => ready(Err( InternalError::DeserializeFromBytes(format!("{}", e)).into(), )), }, } } } impl AFPluginResponder for AFPluginData where T: ToBytes, { fn respond_to(self, _request: &AFPluginEventRequest) -> AFPluginEventResponse { match self.into_inner().into_bytes() { Ok(bytes) => { tracing::trace!( "Serialize Data: {:?} to event response", std::any::type_name::() ); ResponseBuilder::Ok().data(bytes).build() }, Err(e) => e.into(), } } } impl std::convert::TryFrom<&Payload> for AFPluginData where T: AFPluginFromBytes, { type Error = DispatchError; fn try_from(payload: &Payload) -> Result, Self::Error> { parse_payload(payload) } } impl std::convert::TryFrom for AFPluginData where T: AFPluginFromBytes, { type Error = DispatchError; fn try_from(payload: Payload) -> Result, Self::Error> { parse_payload(&payload) } } fn parse_payload(payload: &Payload) -> Result, DispatchError> where T: AFPluginFromBytes, { match payload { Payload::None => Err( InternalError::UnexpectedNone(format!( "Parse fail, expected payload:{:?}", std::any::type_name::() )) .into(), ), Payload::Bytes(bytes) => { let data = T::parse_from_bytes(bytes.clone())?; Ok(AFPluginData(data)) }, } } impl std::convert::TryInto for AFPluginData where T: ToBytes, { type Error = DispatchError; fn try_into(self) -> Result { let inner = self.into_inner(); let bytes = inner.into_bytes()?; Ok(Payload::Bytes(bytes)) } } impl ToBytes for AFPluginData { fn into_bytes(self) -> Result { Ok(Bytes::from(self.0)) } } impl Debug for AFPluginData where T: Debug, { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { self.0.fmt(f) } }