1
0
mirror of https://github.com/fafhrd91/actix-net synced 2024-11-24 02:21:07 +01:00

add RcService type and rc_service construct function (#290)

This commit is contained in:
fakeshadow 2021-02-28 15:01:05 -08:00 committed by GitHub
parent 382830a37e
commit 9e2bcec226
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 47 deletions

View File

@ -2,8 +2,10 @@
## Unreleased - 2021-xx-xx ## Unreleased - 2021-xx-xx
* Add default `Service` trait impl for `Rc<S: Service>` and `&S: Service`. [#288] * Add default `Service` trait impl for `Rc<S: Service>` and `&S: Service`. [#288]
* Add `boxed::rc_service` function for constructing `boxed::RcService` type [#290]
[#288]: https://github.com/actix/actix-net/pull/288 [#288]: https://github.com/actix/actix-net/pull/288
[#290]: https://github.com/actix/actix-net/pull/290
## 2.0.0-beta.4 - 2021-02-04 ## 2.0.0-beta.4 - 2021-02-04

View File

@ -1,7 +1,6 @@
use alloc::boxed::Box; use alloc::{boxed::Box, rc::Rc};
use core::{ use core::{
future::Future, future::Future,
marker::PhantomData,
pin::Pin, pin::Pin,
task::{Context, Poll}, task::{Context, Poll},
}; };
@ -10,12 +9,34 @@ use crate::{Service, ServiceFactory};
pub type BoxFuture<T> = Pin<Box<dyn Future<Output = T>>>; pub type BoxFuture<T> = Pin<Box<dyn Future<Output = T>>>;
pub type BoxService<Req, Res, Err> = macro_rules! service_object {
Box<dyn Service<Req, Response = Res, Error = Err, Future = BoxFuture<Result<Res, Err>>>>; ($name: ident, $type: tt, $fn_name: ident) => {
/// Type alias for service trait object.
pub type $name<Req, Res, Err> = $type<
dyn Service<Req, Response = Res, Error = Err, Future = BoxFuture<Result<Res, Err>>>,
>;
/// Create service trait object.
pub fn $fn_name<S, Req>(service: S) -> $name<Req, S::Response, S::Error>
where
S: Service<Req> + 'static,
Req: 'static,
S::Future: 'static,
{
$type::new(ServiceWrapper(service))
}
};
}
service_object!(BoxService, Box, service);
service_object!(RcService, Rc, rc_service);
/// Type alias for service factory trait object that would produce a trait object service
/// (`BoxService`, `RcService`, etc.)
pub struct BoxServiceFactory<Cfg, Req, Res, Err, InitErr>(Inner<Cfg, Req, Res, Err, InitErr>); pub struct BoxServiceFactory<Cfg, Req, Res, Err, InitErr>(Inner<Cfg, Req, Res, Err, InitErr>);
/// Create boxed service factory /// Create service factory trait object.
pub fn factory<SF, Req>( pub fn factory<SF, Req>(
factory: SF, factory: SF,
) -> BoxServiceFactory<SF::Config, Req, SF::Response, SF::Error, SF::InitError> ) -> BoxServiceFactory<SF::Config, Req, SF::Response, SF::Error, SF::InitError>
@ -28,20 +49,7 @@ where
SF::Error: 'static, SF::Error: 'static,
SF::InitError: 'static, SF::InitError: 'static,
{ {
BoxServiceFactory(Box::new(FactoryWrapper { BoxServiceFactory(Box::new(FactoryWrapper(factory)))
factory,
_t: PhantomData,
}))
}
/// Create boxed service
pub fn service<S, Req>(service: S) -> BoxService<Req, S::Response, S::Error>
where
S: Service<Req> + 'static,
Req: 'static,
S::Future: 'static,
{
Box::new(ServiceWrapper(service, PhantomData))
} }
type Inner<C, Req, Res, Err, InitErr> = Box< type Inner<C, Req, Res, Err, InitErr> = Box<
@ -66,9 +74,9 @@ where
{ {
type Response = Res; type Response = Res;
type Error = Err; type Error = Err;
type InitError = InitErr;
type Config = C; type Config = C;
type Service = BoxService<Req, Res, Err>; type Service = BoxService<Req, Res, Err>;
type InitError = InitErr;
type Future = BoxFuture<Result<Self::Service, InitErr>>; type Future = BoxFuture<Result<Self::Service, InitErr>>;
@ -77,12 +85,9 @@ where
} }
} }
struct FactoryWrapper<SF, Req, Cfg> { struct FactoryWrapper<SF>(SF);
factory: SF,
_t: PhantomData<(Req, Cfg)>,
}
impl<SF, Req, Cfg, Res, Err, InitErr> ServiceFactory<Req> for FactoryWrapper<SF, Req, Cfg> impl<SF, Req, Cfg, Res, Err, InitErr> ServiceFactory<Req> for FactoryWrapper<SF>
where where
Req: 'static, Req: 'static,
Res: 'static, Res: 'static,
@ -95,34 +100,20 @@ where
{ {
type Response = Res; type Response = Res;
type Error = Err; type Error = Err;
type InitError = InitErr;
type Config = Cfg; type Config = Cfg;
type Service = BoxService<Req, Res, Err>; type Service = BoxService<Req, Res, Err>;
type InitError = InitErr;
type Future = BoxFuture<Result<Self::Service, Self::InitError>>; type Future = BoxFuture<Result<Self::Service, Self::InitError>>;
fn new_service(&self, cfg: Cfg) -> Self::Future { fn new_service(&self, cfg: Cfg) -> Self::Future {
let fut = self.factory.new_service(cfg); let f = self.0.new_service(cfg);
Box::pin(async { Box::pin(async { f.await.map(|s| Box::new(ServiceWrapper(s)) as _) })
let res = fut.await;
res.map(ServiceWrapper::boxed)
})
} }
} }
struct ServiceWrapper<S: Service<Req>, Req>(S, PhantomData<Req>); struct ServiceWrapper<S>(S);
impl<S, Req> ServiceWrapper<S, Req> impl<S, Req, Res, Err> Service<Req> for ServiceWrapper<S>
where
S: Service<Req> + 'static,
Req: 'static,
S::Future: 'static,
{
fn boxed(service: S) -> BoxService<Req, S::Response, S::Error> {
Box::new(ServiceWrapper(service, PhantomData))
}
}
impl<S, Req, Res, Err> Service<Req> for ServiceWrapper<S, Req>
where where
S: Service<Req, Response = Res, Error = Err>, S: Service<Req, Response = Res, Error = Err>,
S::Future: 'static, S::Future: 'static,

View File

@ -204,18 +204,18 @@ where
impl<S, Req> Service<Req> for Rc<S> impl<S, Req> Service<Req> for Rc<S>
where where
S: Service<Req>, S: Service<Req> + ?Sized,
{ {
type Response = S::Response; type Response = S::Response;
type Error = S::Error; type Error = S::Error;
type Future = S::Future; type Future = S::Future;
fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
(&**self).poll_ready(ctx) (**self).poll_ready(ctx)
} }
fn call(&self, request: Req) -> S::Future { fn call(&self, request: Req) -> S::Future {
(&**self).call(request) (**self).call(request)
} }
} }