use crate::{ data::container::DataContainer, error::SystemError, module::ModuleData, request::FromRequest, response::Responder, service::{BoxService, Handler, Service, ServiceFactory, ServiceRequest, ServiceResponse}, }; use futures_core::{future::LocalBoxFuture, ready}; use std::{ collections::HashMap, future::Future, hash::Hash, marker::PhantomData, pin::Pin, rc::Rc, task::{Context, Poll}, }; use tokio::sync::{mpsc, mpsc::UnboundedReceiver}; use crate::{ request::{payload::Payload, FlowyRequest}, service::{factory, BoxServiceFactory, HandlerService}, }; use pin_project::pin_project; use std::fmt::Debug; pub type Command = String; pub type ModuleServiceFactory = BoxServiceFactory<(), ServiceRequest, ServiceResponse, SystemError>; #[pin_project::pin_project] pub struct Module { name: String, data: DataContainer, fact_map: HashMap, cmd_rx: UnboundedReceiver, } impl Module { pub fn new(cmd_rx: UnboundedReceiver) -> Self { Self { name: "".to_owned(), data: DataContainer::new(), fact_map: HashMap::new(), cmd_rx, } } pub fn name(mut self, s: &str) -> Self { self.name = s.to_owned(); self } pub fn data(mut self, data: D) -> Self { let module_data = ModuleData::new(data); self.data.insert(module_data); self } pub fn event(mut self, command: Command, handler: H) -> Self where H: Handler, T: FromRequest + 'static, R: Future + 'static, R::Output: Responder + 'static, { self.fact_map.insert(command, factory(HandlerService::new(handler))); self } } impl Future for Module { type Output = (); fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { loop { match ready!(Pin::new(&mut self.cmd_rx).poll_recv(cx)) { None => return Poll::Ready(()), Some(request) => match self.fact_map.get(request.get_id()) { Some(factory) => { let service_future = factory.new_service(()); tokio::task::spawn_local(ModuleServiceFuture { request, service_future, }); }, None => {}, }, } } } } #[pin_project(project = HandlerServiceProj)] pub struct ModuleServiceFuture { request: FlowyRequest, #[pin] service_future: LocalBoxFuture<'static, Result>, } impl Future for ModuleServiceFuture { type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { unimplemented!() } } impl ServiceFactory for Module { type Response = ServiceResponse; type Error = SystemError; type Service = BoxService; type Config = (); type Future = LocalBoxFuture<'static, Result>; fn new_service(&self, cfg: Self::Config) -> Self::Future { unimplemented!() } }