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

service trait takes shared self reference (#247)

This commit is contained in:
fakeshadow 2021-01-22 19:06:22 -08:00 committed by GitHub
parent 874e5f2e50
commit 636cef8868
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 225 additions and 219 deletions

View File

@ -1,6 +1,9 @@
# Changes # Changes
## Unreleased - 2021-xx-xx ## Unreleased - 2021-xx-xx
* Add `Router::recognize_checked` [#247]
[#247]: https://github.com/actix/actix-net/pull/247
## 0.2.6 - 2021-01-09 ## 0.2.6 - 2021-01-09

View File

@ -45,6 +45,24 @@ impl<T, U> Router<T, U> {
None None
} }
pub fn recognize_checked<R, P, F>(
&self,
resource: &mut R,
check: F,
) -> Option<(&T, ResourceId)>
where
F: Fn(&R, &Option<U>) -> bool,
R: Resource<P>,
P: ResourcePath,
{
for item in self.0.iter() {
if item.0.match_path_checked(resource, &check, &item.2) {
return Some((&item.1, ResourceId(item.0.id())));
}
}
None
}
pub fn recognize_mut_checked<R, P, F>( pub fn recognize_mut_checked<R, P, F>(
&mut self, &mut self,
resource: &mut R, resource: &mut R,

View File

@ -36,6 +36,7 @@ slab = "0.4"
tokio = { version = "1", features = ["sync"] } tokio = { version = "1", features = ["sync"] }
[dev-dependencies] [dev-dependencies]
actix-rt = "2.0.0-beta.2"
bytes = "1" bytes = "1"
env_logger = "0.8" env_logger = "0.8"
futures-util = { version = "0.3.7", default-features = false, features = ["sink"] } futures-util = { version = "0.3.7", default-features = false, features = ["sink"] }

View File

@ -58,11 +58,11 @@ where
type Error = (); type Error = ();
type Future = Ready<Result<(), ()>>; type Future = Ready<Result<(), ()>>;
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.service.poll_ready(ctx).map_err(|_| ()) self.service.poll_ready(ctx).map_err(|_| ())
} }
fn call(&mut self, (guard, req): (Option<CounterGuard>, MioStream)) -> Self::Future { fn call(&self, (guard, req): (Option<CounterGuard>, MioStream)) -> Self::Future {
ready(match FromStream::from_mio(req) { ready(match FromStream::from_mio(req) {
Ok(stream) => { Ok(stream) => {
let f = self.service.call(stream); let f = self.service.call(stream);

View File

@ -1,6 +1,12 @@
# Changes # Changes
## Unreleased - 2021-xx-xx ## Unreleased - 2021-xx-xx
* `Service::poll_ready` and `Service::call` take `&self`. [#247]
* `apply_fn` and `apply_fn_factory` would take `Fn(Req, &Service)` function type [#247]
* `apply_cfg` and `apply_cfg_factory` would take `Fn(Req, &Service)` function type [#247]
* `fn_service` module would take `Fn(Req)` function type. [#247]
[#247]: https://github.com/actix/actix-net/pull/247
## 2.0.0-beta.3 - 2021-01-09 ## 2.0.0-beta.3 - 2021-01-09

View File

@ -1,12 +1,12 @@
use alloc::rc::Rc;
use core::{ use core::{
cell::RefCell,
future::Future, future::Future,
marker::PhantomData, marker::PhantomData,
pin::Pin, pin::Pin,
task::{Context, Poll}, task::{Context, Poll},
}; };
use alloc::rc::Rc;
use futures_core::ready;
use pin_project_lite::pin_project; use pin_project_lite::pin_project;
use super::{Service, ServiceFactory}; use super::{Service, ServiceFactory};
@ -15,7 +15,7 @@ use super::{Service, ServiceFactory};
/// of another service which completes successfully. /// of another service which completes successfully.
/// ///
/// This is created by the `Pipeline::and_then` method. /// This is created by the `Pipeline::and_then` method.
pub(crate) struct AndThenService<A, B, Req>(Rc<RefCell<(A, B)>>, PhantomData<Req>); pub(crate) struct AndThenService<A, B, Req>(Rc<(A, B)>, PhantomData<Req>);
impl<A, B, Req> AndThenService<A, B, Req> { impl<A, B, Req> AndThenService<A, B, Req> {
/// Create new `AndThen` combinator /// Create new `AndThen` combinator
@ -24,7 +24,7 @@ impl<A, B, Req> AndThenService<A, B, Req> {
A: Service<Req>, A: Service<Req>,
B: Service<A::Response, Error = A::Error>, B: Service<A::Response, Error = A::Error>,
{ {
Self(Rc::new(RefCell::new((a, b))), PhantomData) Self(Rc::new((a, b)), PhantomData)
} }
} }
@ -43,20 +43,20 @@ where
type Error = A::Error; type Error = A::Error;
type Future = AndThenServiceResponse<A, B, Req>; type Future = AndThenServiceResponse<A, B, Req>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
let mut srv = self.0.borrow_mut(); let (a, b) = &*self.0;
let not_ready = !srv.0.poll_ready(cx)?.is_ready(); let not_ready = !a.poll_ready(cx)?.is_ready();
if !srv.1.poll_ready(cx)?.is_ready() || not_ready { if !b.poll_ready(cx)?.is_ready() || not_ready {
Poll::Pending Poll::Pending
} else { } else {
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} }
} }
fn call(&mut self, req: Req) -> Self::Future { fn call(&self, req: Req) -> Self::Future {
AndThenServiceResponse { AndThenServiceResponse {
state: State::A { state: State::A {
fut: self.0.borrow_mut().0.call(req), fut: self.0 .0.call(req),
b: Some(self.0.clone()), b: Some(self.0.clone()),
}, },
} }
@ -84,13 +84,12 @@ pin_project! {
A { A {
#[pin] #[pin]
fut: A::Future, fut: A::Future,
b: Option<Rc<RefCell<(A, B)>>>, b: Option<Rc<(A, B)>>,
}, },
B { B {
#[pin] #[pin]
fut: B::Future, fut: B::Future,
}, },
Empty,
} }
} }
@ -105,23 +104,14 @@ where
let mut this = self.as_mut().project(); let mut this = self.as_mut().project();
match this.state.as_mut().project() { match this.state.as_mut().project() {
StateProj::A { fut, b } => match fut.poll(cx)? { StateProj::A { fut, b } => {
Poll::Ready(res) => { let res = ready!(fut.poll(cx))?;
let b = b.take().unwrap(); let b = b.take().unwrap();
this.state.set(State::Empty); // drop fut A let fut = b.1.call(res);
let fut = b.borrow_mut().1.call(res); this.state.set(State::B { fut });
this.state.set(State::B { fut }); self.poll(cx)
self.poll(cx)
}
Poll::Pending => Poll::Pending,
},
StateProj::B { fut } => fut.poll(cx).map(|r| {
this.state.set(State::Empty);
r
}),
StateProj::Empty => {
panic!("future must not be polled after it returned `Poll::Ready`")
} }
StateProj::B { fut } => fut.poll(cx),
} }
} }
} }
@ -292,12 +282,12 @@ mod tests {
type Error = (); type Error = ();
type Future = Ready<Result<Self::Response, ()>>; type Future = Ready<Result<Self::Response, ()>>;
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.0.set(self.0.get() + 1); self.0.set(self.0.get() + 1);
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} }
fn call(&mut self, req: &'static str) -> Self::Future { fn call(&self, req: &'static str) -> Self::Future {
ok(req) ok(req)
} }
} }
@ -310,12 +300,12 @@ mod tests {
type Error = (); type Error = ();
type Future = Ready<Result<Self::Response, ()>>; type Future = Ready<Result<Self::Response, ()>>;
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.0.set(self.0.get() + 1); self.0.set(self.0.get() + 1);
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} }
fn call(&mut self, req: &'static str) -> Self::Future { fn call(&self, req: &'static str) -> Self::Future {
ok((req, "srv2")) ok((req, "srv2"))
} }
} }
@ -323,7 +313,7 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn test_poll_ready() { async fn test_poll_ready() {
let cnt = Rc::new(Cell::new(0)); let cnt = Rc::new(Cell::new(0));
let mut srv = pipeline(Srv1(cnt.clone())).and_then(Srv2(cnt.clone())); let srv = pipeline(Srv1(cnt.clone())).and_then(Srv2(cnt.clone()));
let res = lazy(|cx| srv.poll_ready(cx)).await; let res = lazy(|cx| srv.poll_ready(cx)).await;
assert_eq!(res, Poll::Ready(Ok(()))); assert_eq!(res, Poll::Ready(Ok(())));
assert_eq!(cnt.get(), 2); assert_eq!(cnt.get(), 2);
@ -332,7 +322,7 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn test_call() { async fn test_call() {
let cnt = Rc::new(Cell::new(0)); let cnt = Rc::new(Cell::new(0));
let mut srv = pipeline(Srv1(cnt.clone())).and_then(Srv2(cnt)); let srv = pipeline(Srv1(cnt.clone())).and_then(Srv2(cnt));
let res = srv.call("srv1").await; let res = srv.call("srv1").await;
assert!(res.is_ok()); assert!(res.is_ok());
assert_eq!(res.unwrap(), ("srv1", "srv2")); assert_eq!(res.unwrap(), ("srv1", "srv2"));
@ -346,7 +336,7 @@ mod tests {
pipeline_factory(fn_factory(move || ready(Ok::<_, ()>(Srv1(cnt2.clone()))))) pipeline_factory(fn_factory(move || ready(Ok::<_, ()>(Srv1(cnt2.clone())))))
.and_then(move || ready(Ok(Srv2(cnt.clone())))); .and_then(move || ready(Ok(Srv2(cnt.clone()))));
let mut srv = new_srv.new_service(()).await.unwrap(); let srv = new_srv.new_service(()).await.unwrap();
let res = srv.call("srv1").await; let res = srv.call("srv1").await;
assert!(res.is_ok()); assert!(res.is_ok());
assert_eq!(res.unwrap(), ("srv1", "srv2")); assert_eq!(res.unwrap(), ("srv1", "srv2"));

View File

@ -20,7 +20,7 @@ pub fn apply_fn<I, S, F, Fut, Req, In, Res, Err>(
where where
I: IntoService<S, In>, I: IntoService<S, In>,
S: Service<In, Error = Err>, S: Service<In, Error = Err>,
F: FnMut(Req, &mut S) -> Fut, F: Fn(Req, &S) -> Fut,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
Apply::new(service.into_service(), wrap_fn) Apply::new(service.into_service(), wrap_fn)
@ -36,7 +36,7 @@ pub fn apply_fn_factory<I, SF, F, Fut, Req, In, Res, Err>(
where where
I: IntoServiceFactory<SF, In>, I: IntoServiceFactory<SF, In>,
SF: ServiceFactory<In, Error = Err>, SF: ServiceFactory<In, Error = Err>,
F: FnMut(Req, &mut SF::Service) -> Fut + Clone, F: Fn(Req, &SF::Service) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
ApplyFactory::new(service.into_factory(), f) ApplyFactory::new(service.into_factory(), f)
@ -57,7 +57,7 @@ where
impl<S, F, Fut, Req, In, Res, Err> Apply<S, F, Req, In, Res, Err> impl<S, F, Fut, Req, In, Res, Err> Apply<S, F, Req, In, Res, Err>
where where
S: Service<In, Error = Err>, S: Service<In, Error = Err>,
F: FnMut(Req, &mut S) -> Fut, F: Fn(Req, &S) -> Fut,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
/// Create new `Apply` combinator /// Create new `Apply` combinator
@ -73,7 +73,7 @@ where
impl<S, F, Fut, Req, In, Res, Err> Clone for Apply<S, F, Req, In, Res, Err> impl<S, F, Fut, Req, In, Res, Err> Clone for Apply<S, F, Req, In, Res, Err>
where where
S: Service<In, Error = Err> + Clone, S: Service<In, Error = Err> + Clone,
F: FnMut(Req, &mut S) -> Fut + Clone, F: Fn(Req, &S) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -88,7 +88,7 @@ where
impl<S, F, Fut, Req, In, Res, Err> Service<Req> for Apply<S, F, Req, In, Res, Err> impl<S, F, Fut, Req, In, Res, Err> Service<Req> for Apply<S, F, Req, In, Res, Err>
where where
S: Service<In, Error = Err>, S: Service<In, Error = Err>,
F: FnMut(Req, &mut S) -> Fut, F: Fn(Req, &S) -> Fut,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
type Response = Res; type Response = Res;
@ -97,8 +97,8 @@ where
crate::forward_ready!(service); crate::forward_ready!(service);
fn call(&mut self, req: Req) -> Self::Future { fn call(&self, req: Req) -> Self::Future {
(self.wrap_fn)(req, &mut self.service) (self.wrap_fn)(req, &self.service)
} }
} }
@ -112,7 +112,7 @@ pub struct ApplyFactory<SF, F, Req, In, Res, Err> {
impl<SF, F, Fut, Req, In, Res, Err> ApplyFactory<SF, F, Req, In, Res, Err> impl<SF, F, Fut, Req, In, Res, Err> ApplyFactory<SF, F, Req, In, Res, Err>
where where
SF: ServiceFactory<In, Error = Err>, SF: ServiceFactory<In, Error = Err>,
F: FnMut(Req, &mut SF::Service) -> Fut + Clone, F: Fn(Req, &SF::Service) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
/// Create new `ApplyFactory` new service instance /// Create new `ApplyFactory` new service instance
@ -128,7 +128,7 @@ where
impl<SF, F, Fut, Req, In, Res, Err> Clone for ApplyFactory<SF, F, Req, In, Res, Err> impl<SF, F, Fut, Req, In, Res, Err> Clone for ApplyFactory<SF, F, Req, In, Res, Err>
where where
SF: ServiceFactory<In, Error = Err> + Clone, SF: ServiceFactory<In, Error = Err> + Clone,
F: FnMut(Req, &mut SF::Service) -> Fut + Clone, F: Fn(Req, &SF::Service) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -144,7 +144,7 @@ impl<SF, F, Fut, Req, In, Res, Err> ServiceFactory<Req>
for ApplyFactory<SF, F, Req, In, Res, Err> for ApplyFactory<SF, F, Req, In, Res, Err>
where where
SF: ServiceFactory<In, Error = Err>, SF: ServiceFactory<In, Error = Err>,
F: FnMut(Req, &mut SF::Service) -> Fut + Clone, F: Fn(Req, &SF::Service) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
type Response = Res; type Response = Res;
@ -165,7 +165,7 @@ pin_project! {
pub struct ApplyServiceFactoryResponse<SF, F, Fut, Req, In, Res, Err> pub struct ApplyServiceFactoryResponse<SF, F, Fut, Req, In, Res, Err>
where where
SF: ServiceFactory<In, Error = Err>, SF: ServiceFactory<In, Error = Err>,
F: FnMut(Req, &mut SF::Service) -> Fut, F: Fn(Req, &SF::Service) -> Fut,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
#[pin] #[pin]
@ -178,7 +178,7 @@ pin_project! {
impl<SF, F, Fut, Req, In, Res, Err> ApplyServiceFactoryResponse<SF, F, Fut, Req, In, Res, Err> impl<SF, F, Fut, Req, In, Res, Err> ApplyServiceFactoryResponse<SF, F, Fut, Req, In, Res, Err>
where where
SF: ServiceFactory<In, Error = Err>, SF: ServiceFactory<In, Error = Err>,
F: FnMut(Req, &mut SF::Service) -> Fut, F: Fn(Req, &SF::Service) -> Fut,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
fn new(fut: SF::Future, wrap_fn: F) -> Self { fn new(fut: SF::Future, wrap_fn: F) -> Self {
@ -194,7 +194,7 @@ impl<SF, F, Fut, Req, In, Res, Err> Future
for ApplyServiceFactoryResponse<SF, F, Fut, Req, In, Res, Err> for ApplyServiceFactoryResponse<SF, F, Fut, Req, In, Res, Err>
where where
SF: ServiceFactory<In, Error = Err>, SF: ServiceFactory<In, Error = Err>,
F: FnMut(Req, &mut SF::Service) -> Fut, F: Fn(Req, &SF::Service) -> Fut,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
type Output = Result<Apply<SF::Service, F, Req, In, Res, Err>, SF::InitError>; type Output = Result<Apply<SF::Service, F, Req, In, Res, Err>, SF::InitError>;
@ -226,14 +226,14 @@ mod tests {
crate::always_ready!(); crate::always_ready!();
fn call(&mut self, _: ()) -> Self::Future { fn call(&self, _: ()) -> Self::Future {
ok(()) ok(())
} }
} }
#[actix_rt::test] #[actix_rt::test]
async fn test_call() { async fn test_call() {
let mut srv = pipeline(apply_fn(Srv, |req: &'static str, srv| { let srv = pipeline(apply_fn(Srv, |req: &'static str, srv| {
let fut = srv.call(()); let fut = srv.call(());
async move { async move {
fut.await.unwrap(); fut.await.unwrap();
@ -261,7 +261,7 @@ mod tests {
}, },
)); ));
let mut srv = new_srv.new_service(()).await.unwrap(); let srv = new_srv.new_service(()).await.unwrap();
assert_eq!(lazy(|cx| srv.poll_ready(cx)).await, Poll::Ready(Ok(()))); assert_eq!(lazy(|cx| srv.poll_ready(cx)).await, Poll::Ready(Ok(())));

View File

@ -1,17 +1,17 @@
use alloc::rc::Rc;
use core::{ use core::{
cell::RefCell,
future::Future, future::Future,
marker::PhantomData, marker::PhantomData,
pin::Pin, pin::Pin,
task::{Context, Poll}, task::{Context, Poll},
}; };
use alloc::rc::Rc;
use futures_core::ready;
use pin_project_lite::pin_project; use pin_project_lite::pin_project;
use crate::{Service, ServiceFactory}; use crate::{Service, ServiceFactory};
/// Convert `Fn(Config, &mut Service1) -> Future<Service2>` fn to a service factory. /// Convert `Fn(Config, &Service1) -> Future<Service2>` fn to a service factory.
pub fn apply_cfg<S1, Req, F, Cfg, Fut, S2, Err>( pub fn apply_cfg<S1, Req, F, Cfg, Fut, S2, Err>(
srv: S1, srv: S1,
f: F, f: F,
@ -26,17 +26,17 @@ pub fn apply_cfg<S1, Req, F, Cfg, Fut, S2, Err>(
> + Clone > + Clone
where where
S1: Service<Req>, S1: Service<Req>,
F: FnMut(Cfg, &mut S1) -> Fut, F: Fn(Cfg, &S1) -> Fut,
Fut: Future<Output = Result<S2, Err>>, Fut: Future<Output = Result<S2, Err>>,
S2: Service<Req>, S2: Service<Req>,
{ {
ApplyConfigService { ApplyConfigService {
srv: Rc::new(RefCell::new((srv, f))), srv: Rc::new((srv, f)),
_phantom: PhantomData, _phantom: PhantomData,
} }
} }
/// Convert `Fn(Config, &mut ServiceFactory1) -> Future<ServiceFactory2>` fn to a service factory. /// Convert `Fn(Config, &ServiceFactory1) -> Future<ServiceFactory2>` fn to a service factory.
/// ///
/// Service1 get constructed from `T` factory. /// Service1 get constructed from `T` factory.
pub fn apply_cfg_factory<SF, Req, F, Cfg, Fut, S>( pub fn apply_cfg_factory<SF, Req, F, Cfg, Fut, S>(
@ -52,33 +52,33 @@ pub fn apply_cfg_factory<SF, Req, F, Cfg, Fut, S>(
> + Clone > + Clone
where where
SF: ServiceFactory<Req, Config = ()>, SF: ServiceFactory<Req, Config = ()>,
F: FnMut(Cfg, &mut SF::Service) -> Fut, F: Fn(Cfg, &SF::Service) -> Fut,
SF::InitError: From<SF::Error>, SF::InitError: From<SF::Error>,
Fut: Future<Output = Result<S, SF::InitError>>, Fut: Future<Output = Result<S, SF::InitError>>,
S: Service<Req>, S: Service<Req>,
{ {
ApplyConfigServiceFactory { ApplyConfigServiceFactory {
srv: Rc::new(RefCell::new((factory, f))), srv: Rc::new((factory, f)),
_phantom: PhantomData, _phantom: PhantomData,
} }
} }
/// Convert `Fn(Config, &mut Server) -> Future<Service>` fn to NewService\ /// Convert `Fn(Config, &Server) -> Future<Service>` fn to NewService\
struct ApplyConfigService<S1, Req, F, Cfg, Fut, S2, Err> struct ApplyConfigService<S1, Req, F, Cfg, Fut, S2, Err>
where where
S1: Service<Req>, S1: Service<Req>,
F: FnMut(Cfg, &mut S1) -> Fut, F: Fn(Cfg, &S1) -> Fut,
Fut: Future<Output = Result<S2, Err>>, Fut: Future<Output = Result<S2, Err>>,
S2: Service<Req>, S2: Service<Req>,
{ {
srv: Rc<RefCell<(S1, F)>>, srv: Rc<(S1, F)>,
_phantom: PhantomData<(Cfg, Req, Fut, S2)>, _phantom: PhantomData<(Cfg, Req, Fut, S2)>,
} }
impl<S1, Req, F, Cfg, Fut, S2, Err> Clone for ApplyConfigService<S1, Req, F, Cfg, Fut, S2, Err> impl<S1, Req, F, Cfg, Fut, S2, Err> Clone for ApplyConfigService<S1, Req, F, Cfg, Fut, S2, Err>
where where
S1: Service<Req>, S1: Service<Req>,
F: FnMut(Cfg, &mut S1) -> Fut, F: Fn(Cfg, &S1) -> Fut,
Fut: Future<Output = Result<S2, Err>>, Fut: Future<Output = Result<S2, Err>>,
S2: Service<Req>, S2: Service<Req>,
{ {
@ -94,20 +94,20 @@ impl<S1, Req, F, Cfg, Fut, S2, Err> ServiceFactory<Req>
for ApplyConfigService<S1, Req, F, Cfg, Fut, S2, Err> for ApplyConfigService<S1, Req, F, Cfg, Fut, S2, Err>
where where
S1: Service<Req>, S1: Service<Req>,
F: FnMut(Cfg, &mut S1) -> Fut, F: Fn(Cfg, &S1) -> Fut,
Fut: Future<Output = Result<S2, Err>>, Fut: Future<Output = Result<S2, Err>>,
S2: Service<Req>, S2: Service<Req>,
{ {
type Config = Cfg;
type Response = S2::Response; type Response = S2::Response;
type Error = S2::Error; type Error = S2::Error;
type Config = Cfg;
type Service = S2; type Service = S2;
type InitError = Err; type InitError = Err;
type Future = Fut; type Future = Fut;
fn new_service(&self, cfg: Cfg) -> Self::Future { fn new_service(&self, cfg: Cfg) -> Self::Future {
let (t, f) = &mut *self.srv.borrow_mut(); let (t, f) = &*self.srv;
f(cfg, t) f(cfg, t)
} }
} }
@ -116,18 +116,18 @@ where
struct ApplyConfigServiceFactory<SF, Req, F, Cfg, Fut, S> struct ApplyConfigServiceFactory<SF, Req, F, Cfg, Fut, S>
where where
SF: ServiceFactory<Req, Config = ()>, SF: ServiceFactory<Req, Config = ()>,
F: FnMut(Cfg, &mut SF::Service) -> Fut, F: Fn(Cfg, &SF::Service) -> Fut,
Fut: Future<Output = Result<S, SF::InitError>>, Fut: Future<Output = Result<S, SF::InitError>>,
S: Service<Req>, S: Service<Req>,
{ {
srv: Rc<RefCell<(SF, F)>>, srv: Rc<(SF, F)>,
_phantom: PhantomData<(Cfg, Req, Fut, S)>, _phantom: PhantomData<(Cfg, Req, Fut, S)>,
} }
impl<SF, Req, F, Cfg, Fut, S> Clone for ApplyConfigServiceFactory<SF, Req, F, Cfg, Fut, S> impl<SF, Req, F, Cfg, Fut, S> Clone for ApplyConfigServiceFactory<SF, Req, F, Cfg, Fut, S>
where where
SF: ServiceFactory<Req, Config = ()>, SF: ServiceFactory<Req, Config = ()>,
F: FnMut(Cfg, &mut SF::Service) -> Fut, F: Fn(Cfg, &SF::Service) -> Fut,
Fut: Future<Output = Result<S, SF::InitError>>, Fut: Future<Output = Result<S, SF::InitError>>,
S: Service<Req>, S: Service<Req>,
{ {
@ -144,13 +144,13 @@ impl<SF, Req, F, Cfg, Fut, S> ServiceFactory<Req>
where where
SF: ServiceFactory<Req, Config = ()>, SF: ServiceFactory<Req, Config = ()>,
SF::InitError: From<SF::Error>, SF::InitError: From<SF::Error>,
F: FnMut(Cfg, &mut SF::Service) -> Fut, F: Fn(Cfg, &SF::Service) -> Fut,
Fut: Future<Output = Result<S, SF::InitError>>, Fut: Future<Output = Result<S, SF::InitError>>,
S: Service<Req>, S: Service<Req>,
{ {
type Config = Cfg;
type Response = S::Response; type Response = S::Response;
type Error = S::Error; type Error = S::Error;
type Config = Cfg;
type Service = S; type Service = S;
type InitError = SF::InitError; type InitError = SF::InitError;
@ -161,7 +161,7 @@ where
cfg: Some(cfg), cfg: Some(cfg),
store: self.srv.clone(), store: self.srv.clone(),
state: State::A { state: State::A {
fut: self.srv.borrow().0.new_service(()), fut: self.srv.0.new_service(()),
}, },
} }
} }
@ -172,12 +172,12 @@ pin_project! {
where where
SF: ServiceFactory<Req, Config = ()>, SF: ServiceFactory<Req, Config = ()>,
SF::InitError: From<SF::Error>, SF::InitError: From<SF::Error>,
F: FnMut(Cfg, &mut SF::Service) -> Fut, F: Fn(Cfg, &SF::Service) -> Fut,
Fut: Future<Output = Result<S, SF::InitError>>, Fut: Future<Output = Result<S, SF::InitError>>,
S: Service<Req>, S: Service<Req>,
{ {
cfg: Option<Cfg>, cfg: Option<Cfg>,
store: Rc<RefCell<(SF, F)>>, store: Rc<(SF, F)>,
#[pin] #[pin]
state: State<SF, Fut, S, Req>, state: State<SF, Fut, S, Req>,
} }
@ -203,7 +203,7 @@ impl<SF, Req, F, Cfg, Fut, S> Future
where where
SF: ServiceFactory<Req, Config = ()>, SF: ServiceFactory<Req, Config = ()>,
SF::InitError: From<SF::Error>, SF::InitError: From<SF::Error>,
F: FnMut(Cfg, &mut SF::Service) -> Fut, F: Fn(Cfg, &SF::Service) -> Fut,
Fut: Future<Output = Result<S, SF::InitError>>, Fut: Future<Output = Result<S, SF::InitError>>,
S: Service<Req>, S: Service<Req>,
{ {
@ -213,24 +213,20 @@ where
let mut this = self.as_mut().project(); let mut this = self.as_mut().project();
match this.state.as_mut().project() { match this.state.as_mut().project() {
StateProj::A { fut } => match fut.poll(cx)? { StateProj::A { fut } => {
Poll::Pending => Poll::Pending, let svc = ready!(fut.poll(cx))?;
Poll::Ready(svc) => { this.state.set(State::B { svc });
this.state.set(State::B { svc }); self.poll(cx)
self.poll(cx) }
StateProj::B { svc } => {
ready!(svc.poll_ready(cx))?;
{
let (_, f) = &**this.store;
let fut = f(this.cfg.take().unwrap(), svc);
this.state.set(State::C { fut });
} }
}, self.poll(cx)
StateProj::B { svc } => match svc.poll_ready(cx)? { }
Poll::Ready(_) => {
{
let (_, f) = &mut *this.store.borrow_mut();
let fut = f(this.cfg.take().unwrap(), svc);
this.state.set(State::C { fut });
}
self.poll(cx)
}
Poll::Pending => Poll::Pending,
},
StateProj::C { fut } => fut.poll(cx), StateProj::C { fut } => fut.poll(cx),
} }
} }

View File

@ -131,11 +131,11 @@ where
type Error = Err; type Error = Err;
type Future = BoxFuture<Result<Res, Err>>; type Future = BoxFuture<Result<Res, Err>>;
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.0.poll_ready(ctx) self.0.poll_ready(ctx)
} }
fn call(&mut self, req: Req) -> Self::Future { fn call(&self, req: Req) -> Self::Future {
Box::pin(self.0.call(req)) Box::pin(self.0.call(req))
} }
} }

View File

@ -7,7 +7,7 @@ pub fn fn_service<F, Fut, Req, Res, Err, Cfg>(
f: F, f: F,
) -> FnServiceFactory<F, Fut, Req, Res, Err, Cfg> ) -> FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
where where
F: FnMut(Req) -> Fut + Clone, F: Fn(Req) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
FnServiceFactory::new(f) FnServiceFactory::new(f)
@ -39,7 +39,7 @@ where
/// }); /// });
/// ///
/// // construct new service /// // construct new service
/// let mut srv = factory.new_service(()).await?; /// let srv = factory.new_service(()).await?;
/// ///
/// // now we can use `div` service /// // now we can use `div` service
/// let result = srv.call((10, 20)).await?; /// let result = srv.call((10, 20)).await?;
@ -81,7 +81,7 @@ where
/// }); /// });
/// ///
/// // construct new service with config argument /// // construct new service with config argument
/// let mut srv = factory.new_service(10).await?; /// let srv = factory.new_service(10).await?;
/// ///
/// let result = srv.call(10).await?; /// let result = srv.call(10).await?;
/// assert_eq!(result, 100); /// assert_eq!(result, 100);
@ -132,7 +132,7 @@ where
impl<F, Fut, Req, Res, Err> Service<Req> for FnService<F, Fut, Req, Res, Err> impl<F, Fut, Req, Res, Err> Service<Req> for FnService<F, Fut, Req, Res, Err>
where where
F: FnMut(Req) -> Fut, F: Fn(Req) -> Fut,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
type Response = Res; type Response = Res;
@ -141,14 +141,14 @@ where
crate::always_ready!(); crate::always_ready!();
fn call(&mut self, req: Req) -> Self::Future { fn call(&self, req: Req) -> Self::Future {
(self.f)(req) (self.f)(req)
} }
} }
impl<F, Fut, Req, Res, Err> IntoService<FnService<F, Fut, Req, Res, Err>, Req> for F impl<F, Fut, Req, Res, Err> IntoService<FnService<F, Fut, Req, Res, Err>, Req> for F
where where
F: FnMut(Req) -> Fut, F: Fn(Req) -> Fut,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
fn into_service(self) -> FnService<F, Fut, Req, Res, Err> { fn into_service(self) -> FnService<F, Fut, Req, Res, Err> {
@ -158,7 +158,7 @@ where
pub struct FnServiceFactory<F, Fut, Req, Res, Err, Cfg> pub struct FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
where where
F: FnMut(Req) -> Fut, F: Fn(Req) -> Fut,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
f: F, f: F,
@ -167,7 +167,7 @@ where
impl<F, Fut, Req, Res, Err, Cfg> FnServiceFactory<F, Fut, Req, Res, Err, Cfg> impl<F, Fut, Req, Res, Err, Cfg> FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
where where
F: FnMut(Req) -> Fut + Clone, F: Fn(Req) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
fn new(f: F) -> Self { fn new(f: F) -> Self {
@ -177,7 +177,7 @@ where
impl<F, Fut, Req, Res, Err, Cfg> Clone for FnServiceFactory<F, Fut, Req, Res, Err, Cfg> impl<F, Fut, Req, Res, Err, Cfg> Clone for FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
where where
F: FnMut(Req) -> Fut + Clone, F: Fn(Req) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -187,7 +187,7 @@ where
impl<F, Fut, Req, Res, Err> Service<Req> for FnServiceFactory<F, Fut, Req, Res, Err, ()> impl<F, Fut, Req, Res, Err> Service<Req> for FnServiceFactory<F, Fut, Req, Res, Err, ()>
where where
F: FnMut(Req) -> Fut + Clone, F: Fn(Req) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
type Response = Res; type Response = Res;
@ -196,7 +196,7 @@ where
crate::always_ready!(); crate::always_ready!();
fn call(&mut self, req: Req) -> Self::Future { fn call(&self, req: Req) -> Self::Future {
(self.f)(req) (self.f)(req)
} }
} }
@ -204,7 +204,7 @@ where
impl<F, Fut, Req, Res, Err, Cfg> ServiceFactory<Req> impl<F, Fut, Req, Res, Err, Cfg> ServiceFactory<Req>
for FnServiceFactory<F, Fut, Req, Res, Err, Cfg> for FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
where where
F: FnMut(Req) -> Fut + Clone, F: Fn(Req) -> Fut + Clone,
Fut: Future<Output = Result<Res, Err>>, Fut: Future<Output = Result<Res, Err>>,
{ {
type Response = Res; type Response = Res;
@ -318,8 +318,8 @@ where
{ {
type Response = Srv::Response; type Response = Srv::Response;
type Error = Srv::Error; type Error = Srv::Error;
type Service = Srv;
type Config = Cfg; type Config = Cfg;
type Service = Srv;
type InitError = Err; type InitError = Err;
type Future = Fut; type Future = Fut;
@ -364,7 +364,7 @@ mod tests {
async fn test_fn_service() { async fn test_fn_service() {
let new_srv = fn_service(|()| ok::<_, ()>("srv")); let new_srv = fn_service(|()| ok::<_, ()>("srv"));
let mut srv = new_srv.new_service(()).await.unwrap(); let srv = new_srv.new_service(()).await.unwrap();
let res = srv.call(()).await; let res = srv.call(()).await;
assert_eq!(lazy(|cx| srv.poll_ready(cx)).await, Poll::Ready(Ok(()))); assert_eq!(lazy(|cx| srv.poll_ready(cx)).await, Poll::Ready(Ok(())));
assert!(res.is_ok()); assert!(res.is_ok());
@ -373,7 +373,7 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn test_fn_service_service() { async fn test_fn_service_service() {
let mut srv = fn_service(|()| ok::<_, ()>("srv")); let srv = fn_service(|()| ok::<_, ()>("srv"));
let res = srv.call(()).await; let res = srv.call(()).await;
assert_eq!(lazy(|cx| srv.poll_ready(cx)).await, Poll::Ready(Ok(()))); assert_eq!(lazy(|cx| srv.poll_ready(cx)).await, Poll::Ready(Ok(())));
@ -387,7 +387,7 @@ mod tests {
ok::<_, ()>(fn_service(move |()| ok::<_, ()>(("srv", cfg)))) ok::<_, ()>(fn_service(move |()| ok::<_, ()>(("srv", cfg))))
}); });
let mut srv = new_srv.new_service(1).await.unwrap(); let srv = new_srv.new_service(1).await.unwrap();
let res = srv.call(()).await; let res = srv.call(()).await;
assert_eq!(lazy(|cx| srv.poll_ready(cx)).await, Poll::Ready(Ok(()))); assert_eq!(lazy(|cx| srv.poll_ready(cx)).await, Poll::Ready(Ok(())));
assert!(res.is_ok()); assert!(res.is_ok());

View File

@ -69,9 +69,9 @@ use self::ready::{err, ok, ready, Ready};
/// type Error = MyError; /// type Error = MyError;
/// type Future = Pin<Box<Future<Output=Result<Self::Response, Self::Error>>>>; /// type Future = Pin<Box<Future<Output=Result<Self::Response, Self::Error>>>>;
/// ///
/// fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { ... } /// fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { ... }
/// ///
/// fn call(&mut self, req: Self::Request) -> Self::Future { ... } /// fn call(&self, req: Self::Request) -> Self::Future { ... }
/// } /// }
/// ``` /// ```
/// ///
@ -104,7 +104,7 @@ pub trait Service<Req> {
/// # Notes /// # Notes
/// 1. `.poll_ready()` might be called on different task from actual service call. /// 1. `.poll_ready()` might be called on different task from actual service call.
/// 1. In case of chained services, `.poll_ready()` get called for all services at once. /// 1. In case of chained services, `.poll_ready()` get called for all services at once.
fn poll_ready(&mut self, ctx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>>; fn poll_ready(&self, ctx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>>;
/// Process the request and return the response asynchronously. /// Process the request and return the response asynchronously.
/// ///
@ -115,7 +115,7 @@ pub trait Service<Req> {
/// ///
/// Calling `call` without calling `poll_ready` is permitted. The /// Calling `call` without calling `poll_ready` is permitted. The
/// implementation must be resilient to this fact. /// implementation must be resilient to this fact.
fn call(&mut self, req: Req) -> Self::Future; fn call(&self, req: Req) -> Self::Future;
} }
/// Factory for creating `Service`s. /// Factory for creating `Service`s.
@ -158,11 +158,11 @@ where
type Error = S::Error; type Error = S::Error;
type Future = S::Future; type Future = S::Future;
fn poll_ready(&mut 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(&mut self, request: Req) -> S::Future { fn call(&self, request: Req) -> S::Future {
(**self).call(request) (**self).call(request)
} }
} }
@ -175,11 +175,11 @@ where
type Error = S::Error; type Error = S::Error;
type Future = S::Future; type Future = S::Future;
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), S::Error>> { fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll<Result<(), S::Error>> {
(**self).poll_ready(ctx) (**self).poll_ready(ctx)
} }
fn call(&mut self, request: Req) -> S::Future { fn call(&self, request: Req) -> S::Future {
(**self).call(request) (**self).call(request)
} }
} }
@ -192,12 +192,12 @@ where
type Error = S::Error; type Error = S::Error;
type Future = S::Future; type Future = S::Future;
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.borrow_mut().poll_ready(ctx) self.borrow().poll_ready(ctx)
} }
fn call(&mut self, request: Req) -> S::Future { fn call(&self, request: Req) -> S::Future {
self.borrow_mut().call(request) self.borrow().call(request)
} }
} }
@ -209,12 +209,12 @@ where
type Error = S::Error; type Error = S::Error;
type Future = S::Future; type Future = S::Future;
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.borrow_mut().poll_ready(ctx) self.borrow().poll_ready(ctx)
} }
fn call(&mut self, request: Req) -> S::Future { fn call(&self, request: Req) -> S::Future {
(&mut (**self).borrow_mut()).call(request) self.borrow().call(request)
} }
} }
@ -311,8 +311,9 @@ pub mod dev {
#[macro_export] #[macro_export]
macro_rules! always_ready { macro_rules! always_ready {
() => { () => {
#[inline]
fn poll_ready( fn poll_ready(
&mut self, &self,
_: &mut ::core::task::Context<'_>, _: &mut ::core::task::Context<'_>,
) -> ::core::task::Poll<Result<(), Self::Error>> { ) -> ::core::task::Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
@ -323,8 +324,9 @@ macro_rules! always_ready {
#[macro_export] #[macro_export]
macro_rules! forward_ready { macro_rules! forward_ready {
($field:ident) => { ($field:ident) => {
#[inline]
fn poll_ready( fn poll_ready(
&mut self, &self,
cx: &mut ::core::task::Context<'_>, cx: &mut ::core::task::Context<'_>,
) -> ::core::task::Poll<Result<(), Self::Error>> { ) -> ::core::task::Poll<Result<(), Self::Error>> {
self.$field self.$field

View File

@ -58,7 +58,7 @@ where
crate::forward_ready!(service); crate::forward_ready!(service);
fn call(&mut self, req: Req) -> Self::Future { fn call(&self, req: Req) -> Self::Future {
MapFuture::new(self.service.call(req), self.f.clone()) MapFuture::new(self.service.call(req), self.f.clone())
} }
} }
@ -215,21 +215,21 @@ mod tests {
crate::always_ready!(); crate::always_ready!();
fn call(&mut self, _: ()) -> Self::Future { fn call(&self, _: ()) -> Self::Future {
ok(()) ok(())
} }
} }
#[actix_rt::test] #[actix_rt::test]
async fn test_poll_ready() { async fn test_poll_ready() {
let mut srv = Srv.map(|_| "ok"); let srv = Srv.map(|_| "ok");
let res = lazy(|cx| srv.poll_ready(cx)).await; let res = lazy(|cx| srv.poll_ready(cx)).await;
assert_eq!(res, Poll::Ready(Ok(()))); assert_eq!(res, Poll::Ready(Ok(())));
} }
#[actix_rt::test] #[actix_rt::test]
async fn test_call() { async fn test_call() {
let mut srv = Srv.map(|_| "ok"); let srv = Srv.map(|_| "ok");
let res = srv.call(()).await; let res = srv.call(()).await;
assert!(res.is_ok()); assert!(res.is_ok());
assert_eq!(res.unwrap(), "ok"); assert_eq!(res.unwrap(), "ok");
@ -238,7 +238,7 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn test_new_service() { async fn test_new_service() {
let new_srv = (|| ok::<_, ()>(Srv)).into_factory().map(|_| "ok"); let new_srv = (|| ok::<_, ()>(Srv)).into_factory().map(|_| "ok");
let mut srv = new_srv.new_service(&()).await.unwrap(); let srv = new_srv.new_service(&()).await.unwrap();
let res = srv.call(()).await; let res = srv.call(()).await;
assert!(res.is_ok()); assert!(res.is_ok());
assert_eq!(res.unwrap(), ("ok")); assert_eq!(res.unwrap(), ("ok"));

View File

@ -57,11 +57,11 @@ where
type Error = E; type Error = E;
type Future = MapErrFuture<A, Req, F, E>; type Future = MapErrFuture<A, Req, F, E>;
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.service.poll_ready(ctx).map_err(&self.f) self.service.poll_ready(ctx).map_err(&self.f)
} }
fn call(&mut self, req: Req) -> Self::Future { fn call(&self, req: Req) -> Self::Future {
MapErrFuture::new(self.service.call(req), self.f.clone()) MapErrFuture::new(self.service.call(req), self.f.clone())
} }
} }
@ -218,25 +218,25 @@ mod tests {
type Error = (); type Error = ();
type Future = Ready<Result<(), ()>>; type Future = Ready<Result<(), ()>>;
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Err(())) Poll::Ready(Err(()))
} }
fn call(&mut self, _: ()) -> Self::Future { fn call(&self, _: ()) -> Self::Future {
err(()) err(())
} }
} }
#[actix_rt::test] #[actix_rt::test]
async fn test_poll_ready() { async fn test_poll_ready() {
let mut srv = Srv.map_err(|_| "error"); let srv = Srv.map_err(|_| "error");
let res = lazy(|cx| srv.poll_ready(cx)).await; let res = lazy(|cx| srv.poll_ready(cx)).await;
assert_eq!(res, Poll::Ready(Err("error"))); assert_eq!(res, Poll::Ready(Err("error")));
} }
#[actix_rt::test] #[actix_rt::test]
async fn test_call() { async fn test_call() {
let mut srv = Srv.map_err(|_| "error"); let srv = Srv.map_err(|_| "error");
let res = srv.call(()).await; let res = srv.call(()).await;
assert!(res.is_err()); assert!(res.is_err());
assert_eq!(res.err().unwrap(), "error"); assert_eq!(res.err().unwrap(), "error");
@ -245,7 +245,7 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn test_new_service() { async fn test_new_service() {
let new_srv = (|| ok::<_, ()>(Srv)).into_factory().map_err(|_| "error"); let new_srv = (|| ok::<_, ()>(Srv)).into_factory().map_err(|_| "error");
let mut srv = new_srv.new_service(&()).await.unwrap(); let srv = new_srv.new_service(&()).await.unwrap();
let res = srv.call(()).await; let res = srv.call(()).await;
assert!(res.is_err()); assert!(res.is_err());
assert_eq!(res.err().unwrap(), "error"); assert_eq!(res.err().unwrap(), "error");

View File

@ -146,12 +146,12 @@ impl<S: Service<Req>, Req> Service<Req> for Pipeline<S, Req> {
type Future = S::Future; type Future = S::Future;
#[inline] #[inline]
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), S::Error>> { fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll<Result<(), S::Error>> {
self.service.poll_ready(ctx) self.service.poll_ready(ctx)
} }
#[inline] #[inline]
fn call(&mut self, req: Req) -> Self::Future { fn call(&self, req: Req) -> Self::Future {
self.service.call(req) self.service.call(req)
} }
} }

View File

@ -1,12 +1,12 @@
use alloc::rc::Rc;
use core::{ use core::{
cell::RefCell,
future::Future, future::Future,
marker::PhantomData, marker::PhantomData,
pin::Pin, pin::Pin,
task::{Context, Poll}, task::{Context, Poll},
}; };
use alloc::rc::Rc;
use futures_core::ready;
use pin_project_lite::pin_project; use pin_project_lite::pin_project;
use super::{Service, ServiceFactory}; use super::{Service, ServiceFactory};
@ -15,7 +15,7 @@ use super::{Service, ServiceFactory};
/// another service. /// another service.
/// ///
/// This is created by the `Pipeline::then` method. /// This is created by the `Pipeline::then` method.
pub(crate) struct ThenService<A, B, Req>(Rc<RefCell<(A, B)>>, PhantomData<Req>); pub(crate) struct ThenService<A, B, Req>(Rc<(A, B)>, PhantomData<Req>);
impl<A, B, Req> ThenService<A, B, Req> { impl<A, B, Req> ThenService<A, B, Req> {
/// Create new `.then()` combinator /// Create new `.then()` combinator
@ -24,7 +24,7 @@ impl<A, B, Req> ThenService<A, B, Req> {
A: Service<Req>, A: Service<Req>,
B: Service<Result<A::Response, A::Error>, Error = A::Error>, B: Service<Result<A::Response, A::Error>, Error = A::Error>,
{ {
Self(Rc::new(RefCell::new((a, b))), PhantomData) Self(Rc::new((a, b)), PhantomData)
} }
} }
@ -43,20 +43,20 @@ where
type Error = B::Error; type Error = B::Error;
type Future = ThenServiceResponse<A, B, Req>; type Future = ThenServiceResponse<A, B, Req>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
let mut srv = self.0.borrow_mut(); let (a, b) = &*self.0;
let not_ready = !srv.0.poll_ready(cx)?.is_ready(); let not_ready = !a.poll_ready(cx)?.is_ready();
if !srv.1.poll_ready(cx)?.is_ready() || not_ready { if !b.poll_ready(cx)?.is_ready() || not_ready {
Poll::Pending Poll::Pending
} else { } else {
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} }
} }
fn call(&mut self, req: Req) -> Self::Future { fn call(&self, req: Req) -> Self::Future {
ThenServiceResponse { ThenServiceResponse {
state: State::A { state: State::A {
fut: self.0.borrow_mut().0.call(req), fut: self.0 .0.call(req),
b: Some(self.0.clone()), b: Some(self.0.clone()),
}, },
} }
@ -81,9 +81,8 @@ pin_project! {
A: Service<Req>, A: Service<Req>,
B: Service<Result<A::Response, A::Error>>, B: Service<Result<A::Response, A::Error>>,
{ {
A { #[pin] fut: A::Future, b: Option<Rc<RefCell<(A, B)>>> }, A { #[pin] fut: A::Future, b: Option<Rc<(A, B)>> },
B { #[pin] fut: B::Future }, B { #[pin] fut: B::Future },
Empty,
} }
} }
@ -98,23 +97,14 @@ where
let mut this = self.as_mut().project(); let mut this = self.as_mut().project();
match this.state.as_mut().project() { match this.state.as_mut().project() {
StateProj::A { fut, b } => match fut.poll(cx) { StateProj::A { fut, b } => {
Poll::Ready(res) => { let res = ready!(fut.poll(cx));
let b = b.take().unwrap(); let b = b.take().unwrap();
this.state.set(State::Empty); // drop fut A let fut = b.1.call(res);
let fut = b.borrow_mut().1.call(res); this.state.set(State::B { fut });
this.state.set(State::B { fut }); self.poll(cx)
self.poll(cx)
}
Poll::Pending => Poll::Pending,
},
StateProj::B { fut } => fut.poll(cx).map(|r| {
this.state.set(State::Empty);
r
}),
StateProj::Empty => {
panic!("future must not be polled after it returned `Poll::Ready`")
} }
StateProj::B { fut } => fut.poll(cx),
} }
} }
} }
@ -266,12 +256,12 @@ mod tests {
type Error = (); type Error = ();
type Future = Ready<Result<Self::Response, Self::Error>>; type Future = Ready<Result<Self::Response, Self::Error>>;
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.0.set(self.0.get() + 1); self.0.set(self.0.get() + 1);
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} }
fn call(&mut self, req: Result<&'static str, &'static str>) -> Self::Future { fn call(&self, req: Result<&'static str, &'static str>) -> Self::Future {
match req { match req {
Ok(msg) => ok(msg), Ok(msg) => ok(msg),
Err(_) => err(()), Err(_) => err(()),
@ -286,12 +276,12 @@ mod tests {
type Error = (); type Error = ();
type Future = Ready<Result<Self::Response, ()>>; type Future = Ready<Result<Self::Response, ()>>;
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.0.set(self.0.get() + 1); self.0.set(self.0.get() + 1);
Poll::Ready(Err(())) Poll::Ready(Err(()))
} }
fn call(&mut self, req: Result<&'static str, ()>) -> Self::Future { fn call(&self, req: Result<&'static str, ()>) -> Self::Future {
match req { match req {
Ok(msg) => ok((msg, "ok")), Ok(msg) => ok((msg, "ok")),
Err(()) => ok(("srv2", "err")), Err(()) => ok(("srv2", "err")),
@ -302,7 +292,7 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn test_poll_ready() { async fn test_poll_ready() {
let cnt = Rc::new(Cell::new(0)); let cnt = Rc::new(Cell::new(0));
let mut srv = pipeline(Srv1(cnt.clone())).then(Srv2(cnt.clone())); let srv = pipeline(Srv1(cnt.clone())).then(Srv2(cnt.clone()));
let res = lazy(|cx| srv.poll_ready(cx)).await; let res = lazy(|cx| srv.poll_ready(cx)).await;
assert_eq!(res, Poll::Ready(Err(()))); assert_eq!(res, Poll::Ready(Err(())));
assert_eq!(cnt.get(), 2); assert_eq!(cnt.get(), 2);
@ -311,7 +301,7 @@ mod tests {
#[actix_rt::test] #[actix_rt::test]
async fn test_call() { async fn test_call() {
let cnt = Rc::new(Cell::new(0)); let cnt = Rc::new(Cell::new(0));
let mut srv = pipeline(Srv1(cnt.clone())).then(Srv2(cnt)); let srv = pipeline(Srv1(cnt.clone())).then(Srv2(cnt));
let res = srv.call(Ok("srv1")).await; let res = srv.call(Ok("srv1")).await;
assert!(res.is_ok()); assert!(res.is_ok());
@ -328,7 +318,7 @@ mod tests {
let cnt2 = cnt.clone(); let cnt2 = cnt.clone();
let blank = move || ready(Ok::<_, ()>(Srv1(cnt2.clone()))); let blank = move || ready(Ok::<_, ()>(Srv1(cnt2.clone())));
let factory = pipeline_factory(blank).then(move || ready(Ok(Srv2(cnt.clone())))); let factory = pipeline_factory(blank).then(move || ready(Ok(Srv2(cnt.clone()))));
let mut srv = factory.new_service(&()).await.unwrap(); let srv = factory.new_service(&()).await.unwrap();
let res = srv.call(Ok("srv1")).await; let res = srv.call(Ok("srv1")).await;
assert!(res.is_ok()); assert!(res.is_ok());
assert_eq!(res.unwrap(), ("srv1", "ok")); assert_eq!(res.unwrap(), ("srv1", "ok"));

View File

@ -1,4 +1,3 @@
use alloc::{rc::Rc, sync::Arc};
use core::{ use core::{
future::Future, future::Future,
marker::PhantomData, marker::PhantomData,
@ -6,6 +5,8 @@ use core::{
task::{Context, Poll}, task::{Context, Poll},
}; };
use alloc::{rc::Rc, sync::Arc};
use futures_core::ready;
use pin_project_lite::pin_project; use pin_project_lite::pin_project;
use crate::transform_err::TransformMapInitErr; use crate::transform_err::TransformMapInitErr;
@ -47,7 +48,7 @@ where
/// ///
/// actix_service::forward_ready!(service); /// actix_service::forward_ready!(service);
/// ///
/// fn call(&mut self, req: S::Request) -> Self::Future { /// fn call(&self, req: S::Request) -> Self::Future {
/// TimeoutServiceResponse { /// TimeoutServiceResponse {
/// fut: self.service.call(req), /// fut: self.service.call(req),
/// sleep: Delay::new(clock::now() + self.timeout), /// sleep: Delay::new(clock::now() + self.timeout),
@ -127,8 +128,8 @@ where
{ {
type Response = T::Response; type Response = T::Response;
type Error = T::Error; type Error = T::Error;
type InitError = T::InitError;
type Transform = T::Transform; type Transform = T::Transform;
type InitError = T::InitError;
type Future = T::Future; type Future = T::Future;
fn new_transform(&self, service: S) -> T::Future { fn new_transform(&self, service: S) -> T::Future {
@ -142,8 +143,8 @@ where
{ {
type Response = T::Response; type Response = T::Response;
type Error = T::Error; type Error = T::Error;
type InitError = T::InitError;
type Transform = T::Transform; type Transform = T::Transform;
type InitError = T::InitError;
type Future = T::Future; type Future = T::Future;
fn new_transform(&self, service: S) -> T::Future { fn new_transform(&self, service: S) -> T::Future {
@ -229,14 +230,12 @@ where
let mut this = self.as_mut().project(); let mut this = self.as_mut().project();
match this.state.as_mut().project() { match this.state.as_mut().project() {
ApplyTransformFutureStateProj::A { fut } => match fut.poll(cx)? { ApplyTransformFutureStateProj::A { fut } => {
Poll::Ready(srv) => { let srv = ready!(fut.poll(cx))?;
let fut = this.store.0.new_transform(srv); let fut = this.store.0.new_transform(srv);
this.state.set(ApplyTransformFutureState::B { fut }); this.state.set(ApplyTransformFutureState::B { fut });
self.poll(cx) self.poll(cx)
} }
Poll::Pending => Poll::Pending,
},
ApplyTransformFutureStateProj::B { fut } => fut.poll(cx), ApplyTransformFutureStateProj::B { fut } => fut.poll(cx),
} }
} }

View File

@ -79,7 +79,7 @@ where
type Error = Error; type Error = Error;
type Future = LocalBoxFuture<'static, Result<TlsStream<T>, Error>>; type Future = LocalBoxFuture<'static, Result<TlsStream<T>, Error>>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
if self.conns.available(cx) { if self.conns.available(cx) {
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} else { } else {
@ -87,7 +87,7 @@ where
} }
} }
fn call(&mut self, io: T) -> Self::Future { fn call(&self, io: T) -> Self::Future {
let guard = self.conns.get(); let guard = self.conns.get();
let this = self.clone(); let this = self.clone();
Box::pin(async move { Box::pin(async move {

View File

@ -75,7 +75,7 @@ where
type Error = SslError; type Error = SslError;
type Future = AcceptorServiceResponse<T>; type Future = AcceptorServiceResponse<T>;
fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
if self.conns.available(ctx) { if self.conns.available(ctx) {
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} else { } else {
@ -83,7 +83,7 @@ where
} }
} }
fn call(&mut self, io: T) -> Self::Future { fn call(&self, io: T) -> Self::Future {
let ssl_ctx = self.acceptor.context(); let ssl_ctx = self.acceptor.context();
let ssl = Ssl::new(ssl_ctx).expect("Provided SSL acceptor was invalid."); let ssl = Ssl::new(ssl_ctx).expect("Provided SSL acceptor was invalid.");
AcceptorServiceResponse { AcceptorServiceResponse {

View File

@ -80,7 +80,7 @@ where
type Error = io::Error; type Error = io::Error;
type Future = AcceptorServiceFut<T>; type Future = AcceptorServiceFut<T>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
if self.conns.available(cx) { if self.conns.available(cx) {
Poll::Ready(Ok(())) Poll::Ready(Ok(()))
} else { } else {
@ -88,7 +88,7 @@ where
} }
} }
fn call(&mut self, req: T) -> Self::Future { fn call(&self, req: T) -> Self::Future {
AcceptorServiceFut { AcceptorServiceFut {
_guard: self.conns.get(), _guard: self.conns.get(),
fut: self.acceptor.accept(req), fut: self.acceptor.accept(req),

View File

@ -51,7 +51,7 @@ impl<T: Address> Service<Connect<T>> for TcpConnector {
actix_service::always_ready!(); actix_service::always_ready!();
fn call(&mut self, req: Connect<T>) -> Self::Future { fn call(&self, req: Connect<T>) -> Self::Future {
let port = req.port(); let port = req.port();
let Connect { req, addr, .. } = req; let Connect { req, addr, .. } = req;

View File

@ -146,7 +146,7 @@ impl<T: Address> Service<Connect<T>> for Resolver {
actix_service::always_ready!(); actix_service::always_ready!();
fn call(&mut self, req: Connect<T>) -> Self::Future { fn call(&self, req: Connect<T>) -> Self::Future {
if !req.addr.is_none() { if !req.addr.is_none() {
ResolverFuture::Connected(Some(req)) ResolverFuture::Connected(Some(req))
} else if let Ok(ip) = req.host().parse() { } else if let Ok(ip) = req.host().parse() {

View File

@ -80,7 +80,7 @@ impl<T: Address> Service<Connect<T>> for ConnectService {
actix_service::always_ready!(); actix_service::always_ready!();
fn call(&mut self, req: Connect<T>) -> Self::Future { fn call(&self, req: Connect<T>) -> Self::Future {
ConnectServiceResponse { ConnectServiceResponse {
fut: ConnectFuture::Resolve(self.resolver.call(req)), fut: ConnectFuture::Resolve(self.resolver.call(req)),
tcp: self.tcp, tcp: self.tcp,
@ -149,7 +149,7 @@ impl<T: Address> Service<Connect<T>> for TcpConnectService {
actix_service::always_ready!(); actix_service::always_ready!();
fn call(&mut self, req: Connect<T>) -> Self::Future { fn call(&self, req: Connect<T>) -> Self::Future {
TcpConnectServiceResponse { TcpConnectServiceResponse {
fut: ConnectFuture::Resolve(self.resolver.call(req)), fut: ConnectFuture::Resolve(self.resolver.call(req)),
tcp: self.tcp, tcp: self.tcp,

View File

@ -84,7 +84,7 @@ where
actix_service::always_ready!(); actix_service::always_ready!();
fn call(&mut self, stream: Connection<T, U>) -> Self::Future { fn call(&self, stream: Connection<T, U>) -> Self::Future {
trace!("SSL Handshake start for: {:?}", stream.host()); trace!("SSL Handshake start for: {:?}", stream.host());
let (io, stream) = stream.replace(()); let (io, stream) = stream.replace(());
let host = stream.host(); let host = stream.host();
@ -202,7 +202,7 @@ impl<T: Address + 'static> Service<Connect<T>> for OpensslConnectService {
actix_service::always_ready!(); actix_service::always_ready!();
fn call(&mut self, req: Connect<T>) -> Self::Future { fn call(&self, req: Connect<T>) -> Self::Future {
OpensslConnectServiceResponse { OpensslConnectServiceResponse {
fut1: Some(self.tcp.call(req)), fut1: Some(self.tcp.call(req)),
fut2: None, fut2: None,

View File

@ -84,7 +84,7 @@ where
actix_service::always_ready!(); actix_service::always_ready!();
fn call(&mut self, stream: Connection<T, U>) -> Self::Future { fn call(&self, stream: Connection<T, U>) -> Self::Future {
trace!("SSL Handshake start for: {:?}", stream.host()); trace!("SSL Handshake start for: {:?}", stream.host());
let (io, stream) = stream.replace(()); let (io, stream) = stream.replace(());
let host = DNSNameRef::try_from_ascii_str(stream.host()) let host = DNSNameRef::try_from_ascii_str(stream.host())

View File

@ -22,7 +22,7 @@ async fn test_string() {
}) })
}); });
let mut conn = actix_connect::default_connector(); let conn = actix_connect::default_connector();
let addr = format!("localhost:{}", srv.port()); let addr = format!("localhost:{}", srv.port());
let con = conn.call(addr.into()).await.unwrap(); let con = conn.call(addr.into()).await.unwrap();
assert_eq!(con.peer_addr().unwrap(), srv.addr()); assert_eq!(con.peer_addr().unwrap(), srv.addr());
@ -39,7 +39,7 @@ async fn test_rustls_string() {
}) })
}); });
let mut conn = actix_connect::default_connector(); let conn = actix_connect::default_connector();
let addr = format!("localhost:{}", srv.port()); let addr = format!("localhost:{}", srv.port());
let con = conn.call(addr.into()).await.unwrap(); let con = conn.call(addr.into()).await.unwrap();
assert_eq!(con.peer_addr().unwrap(), srv.addr()); assert_eq!(con.peer_addr().unwrap(), srv.addr());
@ -55,13 +55,14 @@ async fn test_static_str() {
}) })
}); });
let mut conn = actix_connect::default_connector(); let conn = actix_connect::default_connector();
let con = conn.call(Connect::with("10", srv.addr())).await.unwrap(); let con = conn.call(Connect::with("10", srv.addr())).await.unwrap();
assert_eq!(con.peer_addr().unwrap(), srv.addr()); assert_eq!(con.peer_addr().unwrap(), srv.addr());
let connect = Connect::new(srv.host().to_owned()); let connect = Connect::new(srv.host().to_owned());
let mut conn = actix_connect::default_connector();
let conn = actix_connect::default_connector();
let con = conn.call(connect).await; let con = conn.call(connect).await;
assert!(con.is_err()); assert!(con.is_err());
} }
@ -78,7 +79,7 @@ async fn test_new_service() {
let factory = actix_connect::default_connector_factory(); let factory = actix_connect::default_connector_factory();
let mut conn = factory.new_service(()).await.unwrap(); let conn = factory.new_service(()).await.unwrap();
let con = conn.call(Connect::with("10", srv.addr())).await.unwrap(); let con = conn.call(Connect::with("10", srv.addr())).await.unwrap();
assert_eq!(con.peer_addr().unwrap(), srv.addr()); assert_eq!(con.peer_addr().unwrap(), srv.addr());
} }
@ -126,7 +127,7 @@ async fn test_custom_resolver() {
let factory = actix_connect::new_connector_factory(resolver); let factory = actix_connect::new_connector_factory(resolver);
let mut conn = factory.new_service(()).await.unwrap(); let conn = factory.new_service(()).await.unwrap();
let con = conn.call(Connect::with("10", srv.addr())).await.unwrap(); let con = conn.call(Connect::with("10", srv.addr())).await.unwrap();
assert_eq!(con.peer_addr().unwrap(), srv.addr()); assert_eq!(con.peer_addr().unwrap(), srv.addr());
} }
@ -144,7 +145,7 @@ async fn test_openssl_uri() {
}) })
}); });
let mut conn = actix_connect::default_connector(); let conn = actix_connect::default_connector();
let addr = http::Uri::try_from(format!("https://localhost:{}", srv.port())).unwrap(); let addr = http::Uri::try_from(format!("https://localhost:{}", srv.port())).unwrap();
let con = conn.call(addr.into()).await.unwrap(); let con = conn.call(addr.into()).await.unwrap();
assert_eq!(con.peer_addr().unwrap(), srv.addr()); assert_eq!(con.peer_addr().unwrap(), srv.addr());
@ -163,7 +164,7 @@ async fn test_rustls_uri() {
}) })
}); });
let mut conn = actix_connect::default_connector(); let conn = actix_connect::default_connector();
let addr = http::Uri::try_from(format!("https://localhost:{}", srv.port())).unwrap(); let addr = http::Uri::try_from(format!("https://localhost:{}", srv.port())).unwrap();
let con = conn.call(addr.into()).await.unwrap(); let con = conn.call(addr.into()).await.unwrap();
assert_eq!(con.peer_addr().unwrap(), srv.addr()); assert_eq!(con.peer_addr().unwrap(), srv.addr());

View File

@ -37,7 +37,7 @@ where
actix_service::forward_ready!(inner); actix_service::forward_ready!(inner);
fn call(&mut self, req: Req) -> Self::Future { fn call(&self, req: Req) -> Self::Future {
let span = (self.make_span)(&req); let span = (self.make_span)(&req);
let _enter = span.as_ref().map(|s| s.enter()); let _enter = span.as_ref().map(|s| s.enter());
@ -229,7 +229,7 @@ mod test {
let span_svc = span!(Level::TRACE, "span_svc"); let span_svc = span!(Level::TRACE, "span_svc");
let trace_service_factory = trace(service_factory, |_: &&str| Some(span_svc.clone())); let trace_service_factory = trace(service_factory, |_: &&str| Some(span_svc.clone()));
let mut service = trace_service_factory.new_service(()).await.unwrap(); let service = trace_service_factory.new_service(()).await.unwrap();
service.call("boo").await.unwrap(); service.call("boo").await.unwrap();
let id = span_svc.id().unwrap().into_u64(); let id = span_svc.id().unwrap().into_u64();

View File

@ -151,7 +151,7 @@ where
actix_service::forward_ready!(service); actix_service::forward_ready!(service);
fn call(&mut self, request: Req) -> Self::Future { fn call(&self, request: Req) -> Self::Future {
TimeoutServiceResponse { TimeoutServiceResponse {
fut: self.service.call(request), fut: self.service.call(request),
sleep: sleep(self.timeout), sleep: sleep(self.timeout),
@ -213,7 +213,7 @@ mod tests {
actix_service::always_ready!(); actix_service::always_ready!();
fn call(&mut self, _: ()) -> Self::Future { fn call(&self, _: ()) -> Self::Future {
let sleep = actix_rt::time::sleep(self.0); let sleep = actix_rt::time::sleep(self.0);
Box::pin(async move { Box::pin(async move {
sleep.await; sleep.await;
@ -227,7 +227,7 @@ mod tests {
let resolution = Duration::from_millis(100); let resolution = Duration::from_millis(100);
let wait_time = Duration::from_millis(50); let wait_time = Duration::from_millis(50);
let mut timeout = TimeoutService::new(resolution, SleepService(wait_time)); let timeout = TimeoutService::new(resolution, SleepService(wait_time));
assert_eq!(timeout.call(()).await, Ok(())); assert_eq!(timeout.call(()).await, Ok(()));
} }
@ -236,7 +236,7 @@ mod tests {
let resolution = Duration::from_millis(100); let resolution = Duration::from_millis(100);
let wait_time = Duration::from_millis(500); let wait_time = Duration::from_millis(500);
let mut timeout = TimeoutService::new(resolution, SleepService(wait_time)); let timeout = TimeoutService::new(resolution, SleepService(wait_time));
assert_eq!(timeout.call(()).await, Err(TimeoutError::Timeout)); assert_eq!(timeout.call(()).await, Err(TimeoutError::Timeout));
} }
@ -249,7 +249,7 @@ mod tests {
Timeout::new(resolution), Timeout::new(resolution),
fn_factory(|| async { Ok::<_, ()>(SleepService(wait_time)) }), fn_factory(|| async { Ok::<_, ()>(SleepService(wait_time)) }),
); );
let mut srv = timeout.new_service(&()).await.unwrap(); let srv = timeout.new_service(&()).await.unwrap();
assert_eq!(srv.call(()).await, Err(TimeoutError::Timeout)); assert_eq!(srv.call(()).await, Err(TimeoutError::Timeout));
} }