1
0
mirror of https://github.com/fafhrd91/actix-net synced 2024-11-27 16:52:58 +01:00

fix auto-traits for service types (#397)

This commit is contained in:
Ali MJ Al-Nasrawy 2021-12-05 01:30:04 +03:00 committed by GitHub
parent 07e3b19461
commit 62ffe5f389
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 56 additions and 17 deletions

View File

@ -1,6 +1,9 @@
# Changes
## Unreleased - 2021-xx-xx
* Service types can now be `Send` and `'static` regardless of request, response, and config types, etc.. [#397]
[#397]: https://github.com/actix/actix-net/pull/397
## 2.0.1 - 2021-10-11

View File

@ -51,7 +51,7 @@ where
{
service: S,
wrap_fn: F,
_phantom: PhantomData<(Req, In, Res, Err)>,
_phantom: PhantomData<fn(Req) -> (In, Res, Err)>,
}
impl<S, F, Fut, Req, In, Res, Err> Apply<S, F, Req, In, Res, Err>
@ -106,7 +106,7 @@ where
pub struct ApplyFactory<SF, F, Req, In, Res, Err> {
factory: SF,
wrap_fn: F,
_phantom: PhantomData<(Req, In, Res, Err)>,
_phantom: PhantomData<fn(Req) -> (In, Res, Err)>,
}
impl<SF, F, Fut, Req, In, Res, Err> ApplyFactory<SF, F, Req, In, Res, Err>
@ -171,7 +171,7 @@ pin_project! {
#[pin]
fut: SF::Future,
wrap_fn: Option<F>,
_phantom: PhantomData<(Req, Res)>,
_phantom: PhantomData<fn(Req) -> Res>,
}
}

View File

@ -105,7 +105,7 @@ where
Fut: Future<Output = Result<Res, Err>>,
{
f: F,
_t: PhantomData<Req>,
_t: PhantomData<fn(Req)>,
}
impl<F, Fut, Req, Res, Err> FnService<F, Fut, Req, Res, Err>
@ -160,7 +160,7 @@ where
Fut: Future<Output = Result<Res, Err>>,
{
f: F,
_t: PhantomData<(Req, Cfg)>,
_t: PhantomData<fn(Req, Cfg)>,
}
impl<F, Fut, Req, Res, Err, Cfg> FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
@ -237,7 +237,7 @@ where
Srv: Service<Req>,
{
f: F,
_t: PhantomData<(Fut, Cfg, Req, Srv, Err)>,
_t: PhantomData<fn(Cfg, Req) -> (Fut, Srv, Err)>,
}
impl<F, Fut, Cfg, Srv, Req, Err> FnServiceConfig<F, Fut, Cfg, Srv, Req, Err>
@ -293,7 +293,7 @@ where
Fut: Future<Output = Result<Srv, Err>>,
{
f: F,
_t: PhantomData<(Cfg, Req)>,
_t: PhantomData<fn(Cfg, Req)>,
}
impl<F, Cfg, Srv, Req, Fut, Err> FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
@ -391,4 +391,40 @@ mod tests {
assert!(res.is_ok());
assert_eq!(res.unwrap(), ("srv", 1));
}
#[actix_rt::test]
async fn test_auto_impl_send() {
use crate::{map_config, ServiceExt, ServiceFactoryExt};
use alloc::rc::Rc;
let srv_1 = fn_service(|_: Rc<u8>| ok::<_, Rc<u8>>(Rc::new(0u8)));
let fac_1 = fn_factory_with_config(|_: Rc<u8>| {
ok::<_, Rc<u8>>(fn_service(|_: Rc<u8>| ok::<_, Rc<u8>>(Rc::new(0u8))))
});
let fac_2 = fn_factory(|| {
ok::<_, Rc<u8>>(fn_service(|_: Rc<u8>| ok::<_, Rc<u8>>(Rc::new(0u8))))
});
fn is_send<T: Send + Sync + Clone>(_: &T) {}
is_send(&fac_1);
is_send(&map_config(fac_1.clone(), |_: Rc<u8>| Rc::new(0u8)));
is_send(&fac_1.clone().map_err(|_| Rc::new(0u8)));
is_send(&fac_1.clone().map(|_| Rc::new(0u8)));
is_send(&fac_1.clone().map_init_err(|_| Rc::new(0u8)));
// `and_then` is always !Send
// is_send(&fac_1.clone().and_then(fac_1.clone()));
is_send(&fac_1.new_service(Rc::new(0u8)).await.unwrap());
is_send(&fac_2);
is_send(&fac_2.new_service(Rc::new(0u8)).await.unwrap());
is_send(&srv_1);
is_send(&ServiceExt::map(srv_1.clone(), |_| Rc::new(0u8)));
is_send(&ServiceExt::map_err(srv_1.clone(), |_| Rc::new(0u8)));
// `and_then` is always !Send
// is_send(&ServiceExt::and_then(srv_1.clone(), srv_1.clone()));
}
}

View File

@ -15,7 +15,7 @@ use super::{Service, ServiceFactory};
pub struct Map<A, F, Req, Res> {
service: A,
f: F,
_t: PhantomData<(Req, Res)>,
_t: PhantomData<fn(Req) -> Res>,
}
impl<A, F, Req, Res> Map<A, F, Req, Res> {
@ -107,7 +107,7 @@ where
pub struct MapServiceFactory<A, F, Req, Res> {
a: A,
f: F,
r: PhantomData<(Res, Req)>,
r: PhantomData<fn(Req) -> Res>,
}
impl<A, F, Req, Res> MapServiceFactory<A, F, Req, Res> {

View File

@ -28,7 +28,7 @@ where
pub struct MapConfig<SF, Req, F, Cfg> {
factory: SF,
cfg_mapper: F,
e: PhantomData<(Cfg, Req)>,
e: PhantomData<fn(Cfg, Req)>,
}
impl<SF, Req, F, Cfg> MapConfig<SF, Req, F, Cfg> {
@ -82,7 +82,7 @@ where
/// `unit_config()` config combinator
pub struct UnitConfig<SF, Cfg, Req> {
factory: SF,
_phantom: PhantomData<(Cfg, Req)>,
_phantom: PhantomData<fn(Cfg, Req)>,
}
impl<SF, Cfg, Req> UnitConfig<SF, Cfg, Req>

View File

@ -15,7 +15,7 @@ use super::{Service, ServiceFactory};
pub struct MapErr<S, Req, F, E> {
service: S,
mapper: F,
_t: PhantomData<(E, Req)>,
_t: PhantomData<fn(Req) -> E>,
}
impl<S, Req, F, E> MapErr<S, Req, F, E> {
@ -111,7 +111,7 @@ where
{
a: SF,
f: F,
e: PhantomData<(E, Req)>,
e: PhantomData<fn(Req) -> E>,
}
impl<SF, Req, F, E> MapErrServiceFactory<SF, Req, F, E>

View File

@ -13,7 +13,7 @@ use super::ServiceFactory;
pub struct MapInitErr<A, F, Req, Err> {
a: A,
f: F,
e: PhantomData<(Req, Err)>,
e: PhantomData<fn(Req) -> Err>,
}
impl<A, F, Req, Err> MapInitErr<A, F, Req, Err>

View File

@ -40,7 +40,7 @@ where
/// Pipeline service - pipeline allows to compose multiple service into one service.
pub(crate) struct Pipeline<S, Req> {
service: S,
_phantom: PhantomData<Req>,
_phantom: PhantomData<fn(Req)>,
}
impl<S, Req> Pipeline<S, Req>
@ -162,7 +162,7 @@ impl<S: Service<Req>, Req> Service<Req> for Pipeline<S, Req> {
/// Pipeline factory
pub(crate) struct PipelineFactory<SF, Req> {
factory: SF,
_phantom: PhantomData<Req>,
_phantom: PhantomData<fn(Req)>,
}
impl<SF, Req> PipelineFactory<SF, Req>

View File

@ -14,7 +14,7 @@ use super::Transform;
pub struct TransformMapInitErr<T, S, Req, F, E> {
transform: T,
mapper: F,
_phantom: PhantomData<(S, Req, E)>,
_phantom: PhantomData<fn(Req) -> (S, E)>,
}
impl<T, S, F, E, Req> TransformMapInitErr<T, S, Req, F, E> {