diff --git a/tower-filter/Cargo.toml b/tower-filter/Cargo.toml index d66f9bc..9829615 100644 --- a/tower-filter/Cargo.toml +++ b/tower-filter/Cargo.toml @@ -10,3 +10,4 @@ tower-service = { version = "0.1", path = "../tower-service" } [dev-dependencies] tower-mock = { version = "0.1", path = "../tower-mock" } +tower-util = { version = "0.1", path = "../tower-util" } diff --git a/tower-filter/tests/filter.rs b/tower-filter/tests/filter.rs index 4fdaa17..910f509 100644 --- a/tower-filter/tests/filter.rs +++ b/tower-filter/tests/filter.rs @@ -2,10 +2,12 @@ extern crate futures; extern crate tower_mock; extern crate tower_filter; extern crate tower_service; +extern crate tower_util; use futures::*; use tower_filter::*; use tower_service::*; +use tower_util::ServiceExt; use std::thread; use std::sync::mpsc; diff --git a/tower-service/src/lib.rs b/tower-service/src/lib.rs index 85cf570..2d317ca 100644 --- a/tower-service/src/lib.rs +++ b/tower-service/src/lib.rs @@ -12,13 +12,10 @@ //! * [`MakeService`](trait.MakeService.html) is essentially a service factory. It //! is responsible for generating `Service` values on demand. -#[macro_use] extern crate futures; use futures::{Future, Poll}; -use std::marker::PhantomData; - /// An asynchronous function from `Request` to a `Response`. /// /// The `Service` trait is a simplified interface making it easy to write @@ -171,14 +168,6 @@ pub trait Service { /// The future response value. type Future: Future; - /// A future yielding the service when it is ready to accept a request. - fn ready(self) -> Ready where Self: Sized { - Ready { - inner: Some(self), - _p: PhantomData, - } - } - /// Returns `Ready` when the service is able to process requests. /// /// If the service is at capacity, then `NotReady` is returned and the task @@ -202,32 +191,6 @@ pub trait Service { fn call(&mut self, req: Request) -> Self::Future; } -/// Future yielding a `Service` once the service is ready to process a request -/// -/// `Ready` values are produced by `Service::ready`. -pub struct Ready { - inner: Option, - _p: PhantomData Request>, -} - -impl Future for Ready -where T: Service, -{ - type Item = T; - type Error = T::Error; - - fn poll(&mut self) -> Poll { - match self.inner { - Some(ref mut service) => { - let _ = try_ready!(service.poll_ready()); - } - None => panic!("called `poll` after future completed"), - } - - Ok(self.inner.take().unwrap().into()) - } -} - /// Creates new `Service` values. /// /// Acts as a service factory. This is useful for cases where new `Service` diff --git a/tower-util/src/ext/mod.rs b/tower-util/src/ext/mod.rs index 2e00dd7..b74ce25 100644 --- a/tower-util/src/ext/mod.rs +++ b/tower-util/src/ext/mod.rs @@ -8,6 +8,7 @@ mod apply; mod from_err; mod map; mod map_err; +mod ready; mod then; pub use self::and_then::AndThen; @@ -15,6 +16,7 @@ pub use self::apply::Apply; pub use self::from_err::FromErr; pub use self::map::Map; pub use self::map_err::MapErr; +pub use self::ready::Ready; pub use self::then::Then; impl ServiceExt for T @@ -25,6 +27,14 @@ where /// An extension trait for `Service`s that provides a variety of convenient /// adapters pub trait ServiceExt: Service { + /// A future yielding the service when it is ready to accept a request. + fn ready(self) -> Ready + where + Self: Sized, + { + Ready::new(self) + } + fn apply(self, f: F) -> Apply where Self: Service + Clone + Sized, diff --git a/tower-util/src/ext/ready.rs b/tower-util/src/ext/ready.rs new file mode 100644 index 0000000..fc29255 --- /dev/null +++ b/tower-util/src/ext/ready.rs @@ -0,0 +1,57 @@ +use std::fmt; +use std::marker::PhantomData; + +use futures::{Future, Poll}; +use tower_service::Service; + +/// Future yielding a `Service` once the service is ready to process a request +/// +/// `Ready` values are produced by `ServiceExt::ready`. +pub struct Ready { + inner: Option, + _p: PhantomData Request>, +} + +impl Ready +where + T: Service, +{ + pub(super) fn new(service: T) -> Self { + Ready { + inner: Some(service), + _p: PhantomData, + } + } +} + +impl Future for Ready +where + T: Service, +{ + type Item = T; + type Error = T::Error; + + fn poll(&mut self) -> Poll { + match self.inner { + Some(ref mut service) => { + let _ = try_ready!(service.poll_ready()); + } + None => panic!("called `poll` after future completed"), + } + + Ok(self.inner.take().unwrap().into()) + } +} + + +impl fmt::Debug for Ready +where + T: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Ready") + .field("inner", &self.inner) + .finish() + } +} +