use std::future::Future; use crate::{ error::{InternalError, SystemError}, module::Event, request::payload::Payload, util::ready::{ready, Ready}, }; use futures_core::ready; use std::{ fmt::Debug, ops, pin::Pin, task::{Context, Poll}, }; #[derive(Clone, Debug)] pub struct EventRequest { pub(crate) id: String, pub(crate) event: Event, } impl EventRequest { pub fn new(event: E, id: String) -> EventRequest where E: Into, { Self { id, event: event.into(), } } } pub trait FromRequest: Sized { type Error: Into; type Future: Future>; fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future; } #[doc(hidden)] impl FromRequest for () { type Error = SystemError; type Future = Ready>; fn from_request(_req: &EventRequest, _payload: &mut Payload) -> Self::Future { ready(Ok(())) } } #[doc(hidden)] impl FromRequest for String { type Error = SystemError; type Future = Ready>; fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future { match &payload { Payload::None => ready(Err(unexpected_none_payload(req))), Payload::Bytes(buf) => ready(Ok(String::from_utf8_lossy(buf).into_owned())), } } } fn unexpected_none_payload(request: &EventRequest) -> SystemError { log::warn!("{:?} expected payload", &request.event); InternalError::new("Expected payload").into() } #[doc(hidden)] impl FromRequest for Result where T: FromRequest, { type Error = SystemError; type Future = FromRequestFuture; fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future { FromRequestFuture { fut: T::from_request(req, payload), } } } #[pin_project::pin_project] pub struct FromRequestFuture { #[pin] fut: Fut, } impl Future for FromRequestFuture where Fut: Future>, { type Output = Result, SystemError>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); let res = ready!(this.fut.poll(cx)); Poll::Ready(Ok(res)) } } 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 } } #[cfg(feature = "use_serde")] impl FromRequest for Data where T: serde::de::DeserializeOwned + 'static, { type Error = SystemError; 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) => { let s = String::from_utf8_lossy(bytes); match serde_json::from_str(s.as_ref()) { Ok(data) => ready(Ok(Data(data))), Err(e) => ready(Err(InternalError::new(format!("{:?}", e)).into())), } }, } } } pub trait FromBytes: Sized { fn parse_from_bytes(bytes: &Vec) -> Result; } #[cfg(not(feature = "use_serde"))] impl FromRequest for Data where T: FromBytes + 'static, { type Error = SystemError; 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) => { let data = T::parse_from_bytes(bytes).unwrap(); ready(Ok(Data(data))) }, } } }