mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
config service and handle & add test
This commit is contained in:
parent
4d91ed147d
commit
3b10e3c101
@ -13,3 +13,7 @@ futures-channel = "0.3.15"
|
||||
futures = "0.3.15"
|
||||
futures-util = "0.3.15"
|
||||
bytes = "0.5"
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1", features = ["full"] }
|
28
rust-lib/flowy-sys/src/data/container.rs
Normal file
28
rust-lib/flowy-sys/src/data/container.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
collections::HashMap,
|
||||
fmt,
|
||||
mem,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct DataContainer {
|
||||
map: HashMap<TypeId, Box<dyn Any>>,
|
||||
}
|
||||
|
||||
impl DataContainer {
|
||||
#[inline]
|
||||
pub fn new() -> DataContainer {
|
||||
DataContainer {
|
||||
map: HashMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert<T: 'static>(&mut self, val: T) -> Option<T> {
|
||||
self.map
|
||||
.insert(TypeId::of::<T>(), Box::new(val))
|
||||
.and_then(downcast_owned)
|
||||
}
|
||||
}
|
||||
|
||||
fn downcast_owned<T: 'static>(boxed: Box<dyn Any>) -> Option<T> { boxed.downcast().ok().map(|boxed| *boxed) }
|
2
rust-lib/flowy-sys/src/data/mod.rs
Normal file
2
rust-lib/flowy-sys/src/data/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod container;
|
||||
pub mod payload;
|
@ -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<SF, Req>(factory: SF) -> BoxServiceFactory<SF::Config, Req, SF::Response, SF::Error, SF::InitError>
|
||||
where
|
||||
SF: ServiceFactory<Req> + '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<Cfg, Req, Res, Err, InitErr>(Inner<Cfg, Req, Res, Err, InitErr>);
|
||||
impl<C, Req, Res, Err, InitErr> ServiceFactory<Req> for BoxServiceFactory<C, Req, Res, Err, InitErr>
|
||||
@ -25,17 +44,25 @@ where
|
||||
type Service = BoxService<Req, Res, Err>;
|
||||
type InitError = InitErr;
|
||||
type Config = C;
|
||||
type Future = LocalBoxFuture<'static, Result<Self::Service, InitErr>>;
|
||||
|
||||
type Future = BoxFuture<Result<Self::Service, InitErr>>;
|
||||
|
||||
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<T> = Pin<Box<dyn Future<Output = T>>>;
|
||||
type Inner<C, Req, Res, Err, InitErr> = Box<
|
||||
dyn ServiceFactory<
|
||||
Req,
|
||||
Config = C,
|
||||
Response = Res,
|
||||
Error = Err,
|
||||
InitError = InitErr,
|
||||
Service = BoxService<Req, Res, Err>,
|
||||
Future = LocalBoxFuture<'static, Result<BoxService<Req, Res, Err>, InitErr>>,
|
||||
>,
|
||||
>;
|
||||
|
||||
pub type BoxService<Req, Res, Err> =
|
||||
Box<dyn Service<Req, Response = Res, Error = Err, Future = BoxFuture<Result<Res, Err>>>>;
|
||||
Box<dyn Service<Req, Response = Res, Error = Err, Future = LocalBoxFuture<'static, Result<Res, Err>>>>;
|
||||
|
||||
pub fn service<S, Req>(service: S) -> BoxService<Req, S::Response, S::Error>
|
||||
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<S> {
|
||||
@ -64,9 +89,7 @@ struct ServiceWrapper<S> {
|
||||
}
|
||||
|
||||
impl<S> ServiceWrapper<S> {
|
||||
fn new(inner: S) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
fn new(inner: S) -> Self { Self { inner } }
|
||||
}
|
||||
|
||||
impl<S, Req, Res, Err> Service<Req> for ServiceWrapper<S>
|
||||
@ -76,11 +99,9 @@ where
|
||||
{
|
||||
type Response = Res;
|
||||
type Error = Err;
|
||||
type Future = BoxFuture<Result<Res, Err>>;
|
||||
type Future = LocalBoxFuture<'static, Result<Res, Err>>;
|
||||
|
||||
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>(SF);
|
||||
@ -98,41 +119,13 @@ where
|
||||
{
|
||||
type Response = Res;
|
||||
type Error = Err;
|
||||
// type Service: Service<Req, Response = Self::Response, Error = Self::Error>;
|
||||
type Service = BoxService<Req, Res, Err>;
|
||||
type InitError = InitErr;
|
||||
type Config = Cfg;
|
||||
type Future = BoxFuture<Result<Self::Service, Self::InitError>>;
|
||||
type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
|
||||
|
||||
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<SF, Req>(
|
||||
factory: SF,
|
||||
) -> BoxServiceFactory<SF::Config, Req, SF::Response, SF::Error, SF::InitError>
|
||||
where
|
||||
SF: ServiceFactory<Req> + '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<C, Req, Res, Err, InitErr> = Box<
|
||||
dyn ServiceFactory<
|
||||
Req,
|
||||
Config = C,
|
||||
Response = Res,
|
||||
Error = Err,
|
||||
InitError = InitErr,
|
||||
Service = BoxService<Req, Res, Err>,
|
||||
Future = BoxFuture<Result<BoxService<Req, Res, Err>, InitErr>>,
|
||||
>,
|
||||
>;
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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<Error>;
|
||||
type Future: Future<Output = Result<Self, Self::Error>>;
|
||||
|
||||
fn from_request(req: &FlowyRequest, payload: &mut Payload) -> Self::Future;
|
||||
}
|
||||
|
||||
pub struct HandlerService<H, T, R>
|
||||
where
|
||||
H: Handler<T, R>,
|
||||
@ -87,7 +80,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// HandlerService is both it's ServiceFactory and Service Type.
|
||||
impl<H, T, R> Service<ServiceRequest> for HandlerService<H, T, R>
|
||||
where
|
||||
H: Handler<T, R>,
|
||||
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
mod data;
|
||||
mod error;
|
||||
mod handler;
|
||||
mod payload;
|
||||
|
@ -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<Error>;
|
||||
type Future: Future<Output = Result<Self, Self::Error>>;
|
||||
|
||||
fn from_request(req: &FlowyRequest, payload: &mut Payload) -> Self::Future;
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl FromRequest for () {
|
||||
type Error = Error;
|
||||
type Future = Ready<Result<(), Error>>;
|
||||
|
||||
fn from_request(req: &FlowyRequest, payload: &mut Payload) -> Self::Future { ready(Ok(())) }
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl FromRequest for String {
|
||||
type Error = Error;
|
||||
type Future = Ready<Result<String, Error>>;
|
||||
|
||||
fn from_request(req: &FlowyRequest, payload: &mut Payload) -> Self::Future { ready(Ok("".to_string())) }
|
||||
}
|
||||
|
@ -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<ResponseData> for String {
|
||||
fn into(self) -> ResponseData {
|
||||
ResponseData::Bytes(self.into_bytes())
|
||||
}
|
||||
fn into(self) -> ResponseData { ResponseData::Bytes(self.into_bytes()) }
|
||||
}
|
||||
|
||||
impl std::convert::Into<ResponseData> for &str {
|
||||
fn into(self) -> ResponseData {
|
||||
self.to_string().into()
|
||||
}
|
||||
fn into(self) -> ResponseData { self.to_string().into() }
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user