From 3b10e3c101a65f39a06e53c1ee53271d8573826e Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 24 Jun 2021 23:37:45 +0800 Subject: [PATCH] config service and handle & add test --- rust-lib/flowy-sys/Cargo.toml | 6 +- rust-lib/flowy-sys/src/data/container.rs | 28 +++++ rust-lib/flowy-sys/src/data/mod.rs | 2 + rust-lib/flowy-sys/src/{ => data}/payload.rs | 0 rust-lib/flowy-sys/src/handler/boxed.rs | 105 +++++++++---------- rust-lib/flowy-sys/src/handler/dispatch.rs | 53 +++++++--- rust-lib/flowy-sys/src/handler/handler.rs | 12 +-- rust-lib/flowy-sys/src/lib.rs | 1 + rust-lib/flowy-sys/src/request/request.rs | 34 ++++++ rust-lib/flowy-sys/src/response/response.rs | 21 ++-- rust-lib/flowy-sys/src/service.rs | 7 ++ rust-lib/rustfmt.toml | 1 - 12 files changed, 178 insertions(+), 92 deletions(-) create mode 100644 rust-lib/flowy-sys/src/data/container.rs create mode 100644 rust-lib/flowy-sys/src/data/mod.rs rename rust-lib/flowy-sys/src/{ => data}/payload.rs (100%) diff --git a/rust-lib/flowy-sys/Cargo.toml b/rust-lib/flowy-sys/Cargo.toml index f5ba95d624..88cc9549b1 100644 --- a/rust-lib/flowy-sys/Cargo.toml +++ b/rust-lib/flowy-sys/Cargo.toml @@ -12,4 +12,8 @@ paste = "1" futures-channel = "0.3.15" futures = "0.3.15" futures-util = "0.3.15" -bytes = "0.5" \ No newline at end of file +bytes = "0.5" + + +[dev-dependencies] +tokio = { version = "1", features = ["full"] } \ No newline at end of file diff --git a/rust-lib/flowy-sys/src/data/container.rs b/rust-lib/flowy-sys/src/data/container.rs new file mode 100644 index 0000000000..4fb5e29df2 --- /dev/null +++ b/rust-lib/flowy-sys/src/data/container.rs @@ -0,0 +1,28 @@ +use std::{ + any::{Any, TypeId}, + collections::HashMap, + fmt, + mem, +}; + +#[derive(Default)] +pub struct DataContainer { + map: HashMap>, +} + +impl DataContainer { + #[inline] + pub fn new() -> DataContainer { + DataContainer { + map: HashMap::default(), + } + } + + pub fn insert(&mut self, val: T) -> Option { + self.map + .insert(TypeId::of::(), Box::new(val)) + .and_then(downcast_owned) + } +} + +fn downcast_owned(boxed: Box) -> Option { boxed.downcast().ok().map(|boxed| *boxed) } diff --git a/rust-lib/flowy-sys/src/data/mod.rs b/rust-lib/flowy-sys/src/data/mod.rs new file mode 100644 index 0000000000..13791c98c2 --- /dev/null +++ b/rust-lib/flowy-sys/src/data/mod.rs @@ -0,0 +1,2 @@ +pub mod container; +pub mod payload; diff --git a/rust-lib/flowy-sys/src/payload.rs b/rust-lib/flowy-sys/src/data/payload.rs similarity index 100% rename from rust-lib/flowy-sys/src/payload.rs rename to rust-lib/flowy-sys/src/data/payload.rs diff --git a/rust-lib/flowy-sys/src/handler/boxed.rs b/rust-lib/flowy-sys/src/handler/boxed.rs index 792ff3929d..cfe06f562d 100644 --- a/rust-lib/flowy-sys/src/handler/boxed.rs +++ b/rust-lib/flowy-sys/src/handler/boxed.rs @@ -1,16 +1,35 @@ -use crate::error::Error; -use crate::payload::Payload; -use crate::request::FlowyRequest; -use crate::response::{FlowyResponse, Responder}; -use crate::service::{Service, ServiceFactory, ServiceRequest, ServiceResponse}; -use crate::util::ready::*; +use crate::{ + error::Error, + payload::Payload, + request::FlowyRequest, + response::{FlowyResponse, Responder}, + service::{Service, ServiceFactory, ServiceRequest, ServiceResponse}, + util::ready::*, +}; use futures_core::ready; use paste::paste; use pin_project::pin_project; -use std::future::Future; -use std::marker::PhantomData; -use std::pin::Pin; -use std::task::{Context, Poll}; +use std::{ + future::Future, + marker::PhantomData, + pin::Pin, + task::{Context, Poll}, +}; + +use futures_core::future::LocalBoxFuture; + +pub fn factory(factory: SF) -> BoxServiceFactory +where + SF: ServiceFactory + 'static, + Req: 'static, + SF::Response: 'static, + SF::Service: 'static, + SF::Future: 'static, + SF::Error: 'static, + SF::InitError: 'static, +{ + BoxServiceFactory(Box::new(FactoryWrapper(factory))) +} pub struct BoxServiceFactory(Inner); impl ServiceFactory for BoxServiceFactory @@ -25,17 +44,25 @@ where type Service = BoxService; type InitError = InitErr; type Config = C; + type Future = LocalBoxFuture<'static, Result>; - type Future = BoxFuture>; - - fn new_service(&self, cfg: C) -> Self::Future { - self.0.new_service(cfg) - } + fn new_service(&self, cfg: C) -> Self::Future { self.0.new_service(cfg) } } -pub type BoxFuture = Pin>>; +type Inner = Box< + dyn ServiceFactory< + Req, + Config = C, + Response = Res, + Error = Err, + InitError = InitErr, + Service = BoxService, + Future = LocalBoxFuture<'static, Result, InitErr>>, + >, +>; + pub type BoxService = - Box>>>; + Box>>>; pub fn service(service: S) -> BoxService where @@ -54,9 +81,7 @@ where type Error = S::Error; type Future = S::Future; - fn call(&self, request: Req) -> S::Future { - (**self).call(request) - } + fn call(&self, request: Req) -> S::Future { (**self).call(request) } } struct ServiceWrapper { @@ -64,9 +89,7 @@ struct ServiceWrapper { } impl ServiceWrapper { - fn new(inner: S) -> Self { - Self { inner } - } + fn new(inner: S) -> Self { Self { inner } } } impl Service for ServiceWrapper @@ -76,11 +99,9 @@ where { type Response = Res; type Error = Err; - type Future = BoxFuture>; + type Future = LocalBoxFuture<'static, Result>; - fn call(&self, req: Req) -> Self::Future { - Box::pin(self.inner.call(req)) - } + fn call(&self, req: Req) -> Self::Future { Box::pin(self.inner.call(req)) } } struct FactoryWrapper(SF); @@ -98,41 +119,13 @@ where { type Response = Res; type Error = Err; - // type Service: Service; type Service = BoxService; type InitError = InitErr; type Config = Cfg; - type Future = BoxFuture>; + type Future = LocalBoxFuture<'static, Result>; fn new_service(&self, cfg: Cfg) -> Self::Future { let f = self.0.new_service(cfg); Box::pin(async { f.await.map(|s| Box::new(ServiceWrapper::new(s)) as _) }) } } - -pub fn factory( - factory: SF, -) -> BoxServiceFactory -where - SF: ServiceFactory + 'static, - Req: 'static, - SF::Response: 'static, - SF::Service: 'static, - SF::Future: 'static, - SF::Error: 'static, - SF::InitError: 'static, -{ - BoxServiceFactory(Box::new(FactoryWrapper(factory))) -} - -type Inner = Box< - dyn ServiceFactory< - Req, - Config = C, - Response = Res, - Error = Err, - InitError = InitErr, - Service = BoxService, - Future = BoxFuture, InitErr>>, - >, ->; diff --git a/rust-lib/flowy-sys/src/handler/dispatch.rs b/rust-lib/flowy-sys/src/handler/dispatch.rs index 0f963069b3..6179bd7bbd 100644 --- a/rust-lib/flowy-sys/src/handler/dispatch.rs +++ b/rust-lib/flowy-sys/src/handler/dispatch.rs @@ -1,8 +1,16 @@ -use crate::error::Error; -use crate::handler::{boxed, BoxServiceFactory, FromRequest, Handler, HandlerService}; -use crate::response::Responder; -use crate::service::{ServiceRequest, ServiceResponse}; -use std::future::Future; +use crate::{ + error::Error, + handler::{boxed, BoxServiceFactory, Handler, HandlerService}, + request::FromRequest, + response::Responder, + service::{ServiceRequest, ServiceResponse}, +}; + +use std::{ + future::Future, + pin::Pin, + task::{Context, Poll}, +}; pub struct HandlerDispatch { service: BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>, @@ -22,15 +30,36 @@ impl HandlerDispatch { } } -pub fn not_found() -> String { - "hello".to_string() -} - #[cfg(test)] mod tests { use super::*; - #[test] - fn extract_string() { - let dispatch = HandlerDispatch::new(not_found); + use crate::{payload::Payload, request::FlowyRequest, service::ServiceFactory}; + + pub async fn no_params() -> String { + println!("no params"); + "hello".to_string() + } + #[tokio::test] + async fn extract_no_params() { + let dispatch = HandlerDispatch::new(no_params); + let resp = response_from_dispatch(dispatch).await; + } + + pub async fn one_params(s: String) -> String { + println!("one params"); + "hello".to_string() + } + + #[tokio::test] + async fn extract_one_params() { + let dispatch = HandlerDispatch::new(one_params); + let resp = response_from_dispatch(dispatch).await; + } + + async fn response_from_dispatch(dispatch: HandlerDispatch) -> ServiceResponse { + let service = dispatch.service.new_service(()).await.unwrap(); + let service_request = ServiceRequest::new(FlowyRequest::default(), Payload::None); + let resp = service.call(service_request).await.unwrap(); + resp } } diff --git a/rust-lib/flowy-sys/src/handler/handler.rs b/rust-lib/flowy-sys/src/handler/handler.rs index bbca8d09c9..f945756e54 100644 --- a/rust-lib/flowy-sys/src/handler/handler.rs +++ b/rust-lib/flowy-sys/src/handler/handler.rs @@ -1,6 +1,6 @@ use crate::error::Error; use crate::payload::Payload; -use crate::request::FlowyRequest; +use crate::request::{FlowyRequest, FromRequest}; use crate::response::{FlowyResponse, Responder}; use crate::service::{Service, ServiceFactory, ServiceRequest, ServiceResponse}; use crate::util::ready::*; @@ -20,13 +20,6 @@ where fn call(&self, param: T) -> R; } -pub trait FromRequest: Sized { - type Error: Into; - type Future: Future>; - - fn from_request(req: &FlowyRequest, payload: &mut Payload) -> Self::Future; -} - pub struct HandlerService where H: Handler, @@ -87,7 +80,6 @@ where } } -/// HandlerService is both it's ServiceFactory and Service Type. impl Service for HandlerService where H: Handler, @@ -247,3 +239,5 @@ mod m { tuple_from_req!(TupleFromRequest4, (0, A), (1, B), (2, C), (3, D)); tuple_from_req!(TupleFromRequest5, (0, A), (1, B), (2, C), (3, D), (4, E)); } + + diff --git a/rust-lib/flowy-sys/src/lib.rs b/rust-lib/flowy-sys/src/lib.rs index b75d4d6631..1502ae6655 100644 --- a/rust-lib/flowy-sys/src/lib.rs +++ b/rust-lib/flowy-sys/src/lib.rs @@ -1,3 +1,4 @@ +mod data; mod error; mod handler; mod payload; diff --git a/rust-lib/flowy-sys/src/request/request.rs b/rust-lib/flowy-sys/src/request/request.rs index 0f5ae48f16..13f5e5b597 100644 --- a/rust-lib/flowy-sys/src/request/request.rs +++ b/rust-lib/flowy-sys/src/request/request.rs @@ -1 +1,35 @@ +use crate::{ + error::Error, + payload::Payload, + util::ready::{ready, Ready}, +}; +use std::future::Future; + pub struct FlowyRequest {} + +impl std::default::Default for FlowyRequest { + fn default() -> Self { Self {} } +} + +pub trait FromRequest: Sized { + type Error: Into; + type Future: Future>; + + fn from_request(req: &FlowyRequest, payload: &mut Payload) -> Self::Future; +} + +#[doc(hidden)] +impl FromRequest for () { + type Error = Error; + type Future = Ready>; + + fn from_request(req: &FlowyRequest, payload: &mut Payload) -> Self::Future { ready(Ok(())) } +} + +#[doc(hidden)] +impl FromRequest for String { + type Error = Error; + type Future = Ready>; + + fn from_request(req: &FlowyRequest, payload: &mut Payload) -> Self::Future { ready(Ok("".to_string())) } +} diff --git a/rust-lib/flowy-sys/src/response/response.rs b/rust-lib/flowy-sys/src/response/response.rs index cebec39536..a9fd41901e 100644 --- a/rust-lib/flowy-sys/src/response/response.rs +++ b/rust-lib/flowy-sys/src/response/response.rs @@ -1,7 +1,8 @@ -use crate::error::Error; -use crate::request::FlowyRequest; -use crate::response::FlowyResponseBuilder; -use crate::response::Responder; +use crate::{ + error::Error, + request::FlowyRequest, + response::{FlowyResponseBuilder, Responder}, +}; use std::future::Future; #[derive(Clone, Copy)] @@ -48,19 +49,13 @@ impl FlowyResponse { impl Responder for FlowyResponse { #[inline] - fn respond_to(self, _: &FlowyRequest) -> FlowyResponse { - self - } + fn respond_to(self, _: &FlowyRequest) -> FlowyResponse { self } } impl std::convert::Into for String { - fn into(self) -> ResponseData { - ResponseData::Bytes(self.into_bytes()) - } + fn into(self) -> ResponseData { ResponseData::Bytes(self.into_bytes()) } } impl std::convert::Into for &str { - fn into(self) -> ResponseData { - self.to_string().into() - } + fn into(self) -> ResponseData { self.to_string().into() } } diff --git a/rust-lib/flowy-sys/src/service.rs b/rust-lib/flowy-sys/src/service.rs index 7dcd26ec45..fba1440353 100644 --- a/rust-lib/flowy-sys/src/service.rs +++ b/rust-lib/flowy-sys/src/service.rs @@ -28,6 +28,13 @@ pub struct ServiceRequest { } impl ServiceRequest { + + pub fn new(req: FlowyRequest, payload: Payload) -> Self { + Self { + req, payload, + } + } + #[inline] pub fn into_parts(self) -> (FlowyRequest, Payload) { (self.req, self.payload) diff --git a/rust-lib/rustfmt.toml b/rust-lib/rustfmt.toml index dad1d66002..aa7891b3e1 100644 --- a/rust-lib/rustfmt.toml +++ b/rust-lib/rustfmt.toml @@ -6,7 +6,6 @@ match_block_trailing_comma = true normalize_comments = true wrap_comments = true merge_imports = true -reorder_impl_items = true use_field_init_shorthand = true use_try_shorthand = true normalize_doc_attributes = true