use std::future::Future; use crate::{ error::{InternalError, SystemError}, module::Event, request::payload::Payload, response::Responder, util::ready::{ready, Ready}, }; use futures_core::ready; use std::{ fmt::Debug, hash::Hash, 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) -> EventRequest where E: Into, { Self { id: uuid::Uuid::new_v4().to_string(), 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!( "Event: {:?} expected payload but payload is empty", &request.event ); InternalError::new("Expected payload but payload is empty").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 In(pub T); impl In { pub fn into_inner(self) -> T { self.0 } } impl ops::Deref for In { type Target = T; fn deref(&self) -> &T { &self.0 } } impl ops::DerefMut for In { fn deref_mut(&mut self) -> &mut T { &mut self.0 } } #[cfg(feature = "use_serde")] impl FromRequest for In 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 data: T = bincode::deserialize(bytes).unwrap(); ready(Ok(In(data))) }, } } } #[cfg(feature = "use_protobuf")] impl FromRequest for In where T: ::protobuf::Message + '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 = ::protobuf::Message::parse_from_bytes(bytes).unwrap(); ready(Ok(In(data))) }, } } }