use crate::{ byte_trait::*, errors::{DispatchError, InternalError}, request::{unexpected_none_payload, EventRequest, FromRequest, Payload}, response::{EventResponse, Responder, ResponseBuilder}, util::ready::{ready, Ready}, }; use bytes::Bytes; use std::ops; pub struct Data(pub T); impl Data { pub fn into_inner(self) -> T { self.0 } } impl ops::Deref for Data { type Target = T; fn deref(&self) -> &T { &self.0 } } impl ops::DerefMut for Data { fn deref_mut(&mut self) -> &mut T { &mut self.0 } } impl FromRequest for Data where T: FromBytes + 'static, { type Error = DispatchError; type Future = Ready>; #[inline] fn from_request(req: &EventRequest, 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(Data(data))), Err(e) => ready(Err(InternalError::DeserializeFromBytes(format!("{}", e)).into())), }, } } } impl Responder for Data where T: ToBytes, { fn respond_to(self, _request: &EventRequest) -> EventResponse { match self.into_inner().into_bytes() { Ok(bytes) => ResponseBuilder::Ok().data(bytes).build(), Err(e) => e.into(), } } } impl std::convert::TryFrom<&Payload> for Data where T: FromBytes, { type Error = DispatchError; fn try_from(payload: &Payload) -> Result, Self::Error> { parse_payload(payload) } } impl std::convert::TryFrom for Data where T: FromBytes, { type Error = DispatchError; fn try_from(payload: Payload) -> Result, Self::Error> { parse_payload(&payload) } } fn parse_payload(payload: &Payload) -> Result, DispatchError> where T: FromBytes, { match payload { Payload::None => Err(InternalError::UnexpectedNone("Parse fail, expected payload".to_string()).into()), Payload::Bytes(bytes) => { let data = T::parse_from_bytes(bytes.clone())?; Ok(Data(data)) }, } } impl std::convert::TryInto for Data 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 Data { fn into_bytes(self) -> Result { Ok(Bytes::from(self.0)) } }