From 07baf63048ac604fd63d8ab2430aa08aa03a37cc Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Thu, 11 Apr 2019 13:38:45 -0700 Subject: [PATCH] Remove bounds of `Service` from `Layer` --- tower-buffer/src/layer.rs | 35 +++++++++++--------------- tower-filter/src/error.rs | 5 ---- tower-filter/src/layer.rs | 20 +++------------ tower-filter/src/lib.rs | 7 +----- tower-layer/src/lib.rs | 33 ++++++------------------ tower-limit/src/concurrency/layer.rs | 16 +++--------- tower-limit/src/concurrency/mod.rs | 1 - tower-limit/src/concurrency/service.rs | 5 +--- tower-limit/src/rate/error.rs | 15 ----------- tower-limit/src/rate/layer.rs | 19 +++----------- tower-limit/src/rate/service.rs | 5 +--- tower-load-shed/src/error.rs | 16 ------------ tower-load-shed/src/layer.rs | 19 +++----------- tower-retry/src/lib.rs | 23 +++++------------ tower-timeout/src/layer.rs | 17 ++++--------- tower-timeout/src/lib.rs | 1 - tower-timeout/src/never.rs | 12 --------- tower-util/src/layer/identity.rs | 26 +++---------------- tower-util/src/layer/stack.rs | 21 +++++----------- tower/src/builder/mod.rs | 16 ++++++------ tower/src/builder/service.rs | 24 ++++++------------ tower/tests/builder.rs | 3 +-- 22 files changed, 78 insertions(+), 261 deletions(-) diff --git a/tower-buffer/src/layer.rs b/tower-buffer/src/layer.rs index 900f739..10c4f5c 100644 --- a/tower-buffer/src/layer.rs +++ b/tower-buffer/src/layer.rs @@ -1,50 +1,45 @@ use crate::{error::Error, service::Buffer, worker::WorkerExecutor}; +use std::marker::PhantomData; use tokio_executor::DefaultExecutor; use tower_layer::Layer; use tower_service::Service; /// Buffer requests with a bounded buffer -pub struct BufferLayer { +pub struct BufferLayer { bound: usize, executor: E, + _p: PhantomData, } -impl BufferLayer { +impl BufferLayer { pub fn new(bound: usize) -> Self { BufferLayer { bound, executor: DefaultExecutor::current(), + _p: PhantomData, } } } -impl BufferLayer { - pub fn with_executor(bound: usize, executor: E) -> Self - where - S: Service, - S::Error: Into, - E: WorkerExecutor + Clone, - { - BufferLayer { bound, executor } +impl BufferLayer { + pub fn with_executor(bound: usize, executor: E) -> Self { + BufferLayer { + bound, + executor, + _p: PhantomData, + } } } -impl Layer for BufferLayer +impl Layer for BufferLayer where S: Service, S::Error: Into, E: WorkerExecutor + Clone, { - type Response = S::Response; - type Error = Error; - type LayerError = Error; type Service = Buffer; - fn layer(&self, service: S) -> Result { - Ok(Buffer::with_executor( - service, - self.bound, - &mut self.executor.clone(), - )) + fn layer(&self, service: S) -> Self::Service { + Buffer::with_executor(service, self.bound, &mut self.executor.clone()) } } diff --git a/tower-filter/src/error.rs b/tower-filter/src/error.rs index f6e06bd..0f0f7d8 100644 --- a/tower-filter/src/error.rs +++ b/tower-filter/src/error.rs @@ -46,8 +46,3 @@ impl error::Error for Error { } } } - -pub(crate) mod never { - #[derive(Debug)] - pub enum Never {} -} diff --git a/tower-filter/src/layer.rs b/tower-filter/src/layer.rs index e78c1a9..d6735f4 100644 --- a/tower-filter/src/layer.rs +++ b/tower-filter/src/layer.rs @@ -1,9 +1,5 @@ -use crate::{ - error::{self, Error}, - Filter, Predicate, -}; +use crate::Filter; use tower_layer::Layer; -use tower_service::Service; pub struct FilterLayer { predicate: U, @@ -15,19 +11,11 @@ impl FilterLayer { } } -impl Layer for FilterLayer -where - U: Predicate + Clone, - S: Service + Clone, - S::Error: Into, -{ - type Response = S::Response; - type Error = Error; - type LayerError = error::never::Never; +impl Layer for FilterLayer { type Service = Filter; - fn layer(&self, service: S) -> Result { + fn layer(&self, service: S) -> Self::Service { let predicate = self.predicate.clone(); - Ok(Filter::new(service, predicate)) + Filter::new(service, predicate) } } diff --git a/tower-filter/src/lib.rs b/tower-filter/src/lib.rs index 9277643..a21ca6c 100644 --- a/tower-filter/src/lib.rs +++ b/tower-filter/src/lib.rs @@ -22,12 +22,7 @@ pub struct Filter { } impl Filter { - pub fn new(inner: T, predicate: U) -> Self - where - T: Service + Clone, - T::Error: Into, - U: Predicate, - { + pub fn new(inner: T, predicate: U) -> Self { Filter { inner, predicate } } } diff --git a/tower-layer/src/lib.rs b/tower-layer/src/lib.rs index 56055b6..dd43613 100644 --- a/tower-layer/src/lib.rs +++ b/tower-layer/src/lib.rs @@ -8,8 +8,6 @@ //! //! A middleware implements the [`Layer`] and [`Service`] trait. -use tower_service::Service; - /// Decorates a `Service`, transforming either the request or the response. /// /// Often, many of the pieces needed for writing network applications can be @@ -36,21 +34,14 @@ use tower_service::Service; /// target: &'static str, /// } /// -/// impl Layer for LogLayer -/// where -/// S: Service, -/// Request: fmt::Debug, -/// { -/// type Response = S::Response; -/// type Error = S::Error; -/// type LayerError = Void; +/// impl Layer for LogLayer { /// type Service = LogService; /// -/// fn layer(&self, service: S) -> Result { -/// Ok(LogService { +/// fn layer(&self, service: S) -> Self::Service { +/// LogService { /// target: self.target, /// service -/// }) +/// } /// } /// } /// @@ -84,20 +75,10 @@ use tower_service::Service; /// The above log implementation is decoupled from the underlying protocol and /// is also decoupled from client or server concerns. In other words, the same /// log middleware could be used in either a client or a server. -pub trait Layer { - /// The wrapped service response type - type Response; - - /// The wrapped service's error type - type Error; - - /// The error produced when calling `layer` - type LayerError; - +pub trait Layer { /// The wrapped service - type Service: Service; - + type Service; /// Wrap the given service with the middleware, returning a new service /// that has been decorated with the middleware. - fn layer(&self, inner: S) -> Result; + fn layer(&self, inner: S) -> Self::Service; } diff --git a/tower-limit/src/concurrency/layer.rs b/tower-limit/src/concurrency/layer.rs index 30f7f22..24b0e81 100644 --- a/tower-limit/src/concurrency/layer.rs +++ b/tower-limit/src/concurrency/layer.rs @@ -1,6 +1,5 @@ -use super::{never::Never, ConcurrencyLimit, Error}; +use super::ConcurrencyLimit; use tower_layer::Layer; -use tower_service::Service; #[derive(Debug, Clone)] pub struct ConcurrencyLimitLayer { @@ -13,17 +12,10 @@ impl ConcurrencyLimitLayer { } } -impl Layer for ConcurrencyLimitLayer -where - S: Service, - S::Error: Into, -{ - type Response = S::Response; - type Error = Error; - type LayerError = Never; +impl Layer for ConcurrencyLimitLayer { type Service = ConcurrencyLimit; - fn layer(&self, service: S) -> Result { - Ok(ConcurrencyLimit::new(service, self.max)) + fn layer(&self, service: S) -> Self::Service { + ConcurrencyLimit::new(service, self.max) } } diff --git a/tower-limit/src/concurrency/mod.rs b/tower-limit/src/concurrency/mod.rs index de9cf2a..467514e 100644 --- a/tower-limit/src/concurrency/mod.rs +++ b/tower-limit/src/concurrency/mod.rs @@ -2,7 +2,6 @@ pub mod future; mod layer; -mod never; mod service; pub use self::{layer::ConcurrencyLimitLayer, service::ConcurrencyLimit}; diff --git a/tower-limit/src/concurrency/service.rs b/tower-limit/src/concurrency/service.rs index 61e6494..bd201cb 100644 --- a/tower-limit/src/concurrency/service.rs +++ b/tower-limit/src/concurrency/service.rs @@ -20,10 +20,7 @@ struct Limit { impl ConcurrencyLimit { /// Create a new rate limiter - pub fn new(inner: T, max: usize) -> Self - where - T: Service, - { + pub fn new(inner: T, max: usize) -> Self { ConcurrencyLimit { inner, limit: Limit { diff --git a/tower-limit/src/rate/error.rs b/tower-limit/src/rate/error.rs index 59b3a91..712f34d 100644 --- a/tower-limit/src/rate/error.rs +++ b/tower-limit/src/rate/error.rs @@ -1,18 +1,3 @@ use std::error; pub(crate) type Error = Box; - -pub(crate) mod never { - use std::{error, fmt}; - - #[derive(Debug)] - pub enum Never {} - - impl fmt::Display for Never { - fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { - unreachable!(); - } - } - - impl error::Error for Never {} -} diff --git a/tower-limit/src/rate/layer.rs b/tower-limit/src/rate/layer.rs index 2652839..c4157f1 100644 --- a/tower-limit/src/rate/layer.rs +++ b/tower-limit/src/rate/layer.rs @@ -1,10 +1,6 @@ -use super::{ - error::{never::Never, Error}, - Rate, RateLimit, -}; +use super::{Rate, RateLimit}; use std::time::Duration; use tower_layer::Layer; -use tower_service::Service; #[derive(Debug)] pub struct RateLimitLayer { @@ -18,17 +14,10 @@ impl RateLimitLayer { } } -impl Layer for RateLimitLayer -where - S: Service, - Error: From, -{ - type Response = S::Response; - type Error = Error; - type LayerError = Never; +impl Layer for RateLimitLayer { type Service = RateLimit; - fn layer(&self, service: S) -> Result { - Ok(RateLimit::new(service, self.rate)) + fn layer(&self, service: S) -> Self::Service { + RateLimit::new(service, self.rate) } } diff --git a/tower-limit/src/rate/service.rs b/tower-limit/src/rate/service.rs index 10cb99f..a5bfb57 100644 --- a/tower-limit/src/rate/service.rs +++ b/tower-limit/src/rate/service.rs @@ -21,10 +21,7 @@ enum State { impl RateLimit { /// Create a new rate limiter - pub fn new(inner: T, rate: Rate) -> Self - where - T: Service, - { + pub fn new(inner: T, rate: Rate) -> Self { let state = State::Ready { until: clock::now(), rem: rate.num(), diff --git a/tower-load-shed/src/error.rs b/tower-load-shed/src/error.rs index c37540e..7a072fb 100644 --- a/tower-load-shed/src/error.rs +++ b/tower-load-shed/src/error.rs @@ -3,7 +3,6 @@ use std::fmt; pub(crate) type Error = Box; -pub(crate) use self::never::Never; /// An error returned by `Overload` when the underlying service /// is not ready to handle any requests at the time of being @@ -31,18 +30,3 @@ impl fmt::Display for Overloaded { } impl std::error::Error for Overloaded {} - -pub(crate) mod never { - use std::{error, fmt}; - - #[derive(Debug)] - pub enum Never {} - - impl fmt::Display for Never { - fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { - match *self {} - } - } - - impl error::Error for Never {} -} diff --git a/tower-load-shed/src/layer.rs b/tower-load-shed/src/layer.rs index 83f9468..7b578d0 100644 --- a/tower-load-shed/src/layer.rs +++ b/tower-load-shed/src/layer.rs @@ -1,10 +1,6 @@ use tower_layer::Layer; -use tower_service::Service; -use crate::{ - error::{Error, Never}, - LoadShed, -}; +use crate::LoadShed; /// A `tower-layer` to wrap services in `LoadShed` middleware. #[derive(Debug)] @@ -19,17 +15,10 @@ impl LoadShedLayer { } } -impl Layer for LoadShedLayer -where - S: Service, - S::Error: Into, -{ - type Response = S::Response; - type Error = Error; - type LayerError = Never; +impl Layer for LoadShedLayer { type Service = LoadShed; - fn layer(&self, service: S) -> Result { - Ok(LoadShed::new(service)) + fn layer(&self, service: S) -> Self::Service { + LoadShed::new(service) } } diff --git a/tower-retry/src/lib.rs b/tower-retry/src/lib.rs index fc91142..cac25b8 100644 --- a/tower-retry/src/lib.rs +++ b/tower-retry/src/lib.rs @@ -1,6 +1,6 @@ #![deny(missing_debug_implementations)] #![deny(missing_docs)] -#![deny(warnings)] +// #![deny(warnings)] #![deny(rust_2018_idioms)] #![allow(elided_lifetimes_in_paths)] @@ -11,9 +11,6 @@ use tower_layer::Layer; use tower_service::Service; pub mod budget; -mod never; - -use crate::never::Never; /// A "retry policy" to classify if a request should be retried. /// @@ -127,19 +124,15 @@ impl

RetryLayer

{ } } -impl Layer for RetryLayer

+impl Layer for RetryLayer

where - S: Service + Clone, - P: Policy + Clone, + P: Clone, { - type Response = S::Response; - type Error = S::Error; - type LayerError = Never; type Service = Retry; - fn layer(&self, service: S) -> Result { + fn layer(&self, service: S) -> Self::Service { let policy = self.policy.clone(); - Ok(Retry::new(policy, service)) + Retry::new(policy, service) } } @@ -147,11 +140,7 @@ where impl Retry { /// Retry the inner service depending on this [`Policy`][Policy}. - pub fn new(policy: P, service: S) -> Self - where - P: Policy + Clone, - S: Service + Clone, - { + pub fn new(policy: P, service: S) -> Self { Retry { policy, service } } } diff --git a/tower-timeout/src/layer.rs b/tower-timeout/src/layer.rs index fbf3680..e165ce1 100644 --- a/tower-timeout/src/layer.rs +++ b/tower-timeout/src/layer.rs @@ -1,7 +1,7 @@ -use crate::{never::Never, Error, Timeout}; +use crate::Timeout; use std::time::Duration; use tower_layer::Layer; -use tower_service::Service; + /// Applies a timeout to requests via the supplied inner service. #[derive(Debug)] pub struct TimeoutLayer { @@ -15,17 +15,10 @@ impl TimeoutLayer { } } -impl Layer for TimeoutLayer -where - S: Service, - Error: From, -{ - type Response = S::Response; - type Error = Error; - type LayerError = Never; +impl Layer for TimeoutLayer { type Service = Timeout; - fn layer(&self, service: S) -> Result { - Ok(Timeout::new(service, self.timeout)) + fn layer(&self, service: S) -> Self::Service { + Timeout::new(service, self.timeout) } } diff --git a/tower-timeout/src/lib.rs b/tower-timeout/src/lib.rs index d58d7c4..8d2fb76 100644 --- a/tower-timeout/src/lib.rs +++ b/tower-timeout/src/lib.rs @@ -11,7 +11,6 @@ pub mod error; pub mod future; mod layer; -mod never; pub use crate::layer::TimeoutLayer; diff --git a/tower-timeout/src/never.rs b/tower-timeout/src/never.rs index 3bb12aa..e69de29 100644 --- a/tower-timeout/src/never.rs +++ b/tower-timeout/src/never.rs @@ -1,12 +0,0 @@ -use std::fmt; -#[derive(Debug)] -/// An error that can never occur. -pub enum Never {} - -impl fmt::Display for Never { - fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { - match *self {} - } -} - -impl std::error::Error for Never {} diff --git a/tower-util/src/layer/identity.rs b/tower-util/src/layer/identity.rs index 1209b86..e56c9c8 100644 --- a/tower-util/src/layer/identity.rs +++ b/tower-util/src/layer/identity.rs @@ -1,6 +1,4 @@ -use std::fmt; use tower_layer::Layer; -use tower_service::Service; /// A no-op middleware. /// @@ -19,28 +17,10 @@ impl Identity { } /// Decorates a `Service`, transforming either the request or the response. -impl Layer for Identity -where - S: Service, -{ - type Response = S::Response; - type Error = S::Error; - type LayerError = Never; +impl Layer for Identity { type Service = S; - fn layer(&self, inner: S) -> Result { - Ok(inner) + fn layer(&self, inner: S) -> Self::Service { + inner } } - -/// An error that can never occur. -#[derive(Debug)] -pub enum Never {} - -impl fmt::Display for Never { - fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { - match *self {} - } -} - -impl ::std::error::Error for Never {} diff --git a/tower-util/src/layer/stack.rs b/tower-util/src/layer/stack.rs index 3b0b5eb..6e76da8 100644 --- a/tower-util/src/layer/stack.rs +++ b/tower-util/src/layer/stack.rs @@ -1,5 +1,4 @@ use tower_layer::Layer; -use tower_service::Service; /// Two middlewares chained together. /// @@ -10,8 +9,6 @@ pub struct Stack { outer: Outer, } -type Error = Box; - impl Stack { /// Create a new `Stack`. pub fn new(inner: Inner, outer: Outer) -> Self { @@ -19,22 +16,16 @@ impl Stack { } } -impl Layer for Stack +impl Layer for Stack where - S: Service, - Inner: Layer, - Inner::LayerError: Into, - Outer: Layer, - Outer::LayerError: Into, + Inner: Layer, + Outer: Layer, { - type Response = Outer::Response; - type Error = Outer::Error; - type LayerError = Error; type Service = Outer::Service; - fn layer(&self, service: S) -> Result { - let inner = self.inner.layer(service).map_err(Into::into)?; + fn layer(&self, service: S) -> Self::Service { + let inner = self.inner.layer(service); - self.outer.layer(inner).map_err(Into::into) + self.outer.layer(inner) } } diff --git a/tower/src/builder/mod.rs b/tower/src/builder/mod.rs index 6702b05..2ba968d 100644 --- a/tower/src/builder/mod.rs +++ b/tower/src/builder/mod.rs @@ -73,7 +73,7 @@ pub(super) type Error = Box; /// # T::Error: Into>, /// # { /// ServiceBuilder::new() -/// .buffer(100) +/// // .buffer(100) /// .concurrency_limit(10) /// .service(my_service) /// # ; @@ -96,7 +96,7 @@ pub(super) type Error = Box; /// # { /// ServiceBuilder::new() /// .concurrency_limit(10) -/// .buffer(100) +/// // .buffer(100) /// .service(my_service) /// # ; /// # } @@ -207,12 +207,12 @@ pub(super) type Error = Box; /// # } /// # } /// ServiceBuilder::new() -/// .buffer(5) +/// // .buffer(5) /// .concurrency_limit(5) /// .rate_limit(5, Duration::from_secs(1)) /// .service(MyService); /// ``` -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct ServiceBuilder { layer: L, } @@ -235,7 +235,7 @@ impl ServiceBuilder { } /// Buffer requests when when the next layer is out of capacity. - pub fn buffer(self, bound: usize) -> ServiceBuilder> { + pub fn buffer(self, bound: usize) -> ServiceBuilder, L>> { self.layer(BufferLayer::new(bound)) } @@ -291,10 +291,10 @@ impl ServiceBuilder { } /// Wrap the service `S` with the layers. - pub fn service(self, service: S) -> Result + pub fn service(self, service: S) -> L::Service where - L: Layer, - S: Service, + L: Layer, + L::Service: Service, { self.layer.layer(service) } diff --git a/tower/src/builder/service.rs b/tower/src/builder/service.rs index 846381f..b124737 100644 --- a/tower/src/builder/service.rs +++ b/tower/src/builder/service.rs @@ -1,4 +1,3 @@ -use super::Error; use crate::Service; use futures::{try_ready, Async, Future, Poll}; use std::{marker::PhantomData, sync::Arc}; @@ -36,17 +35,15 @@ impl LayeredMakeService { impl Service for LayeredMakeService where S: MakeService, - S::MakeError: Into, - L: Layer + Sync + Send + 'static, - L::LayerError: Into, + L: Layer + Sync + Send + 'static, Target: Clone, { type Response = L::Service; - type Error = Error; + type Error = S::MakeError; type Future = ServiceFuture; fn poll_ready(&mut self) -> Poll<(), Self::Error> { - self.maker.poll_ready().map_err(Into::into) + self.maker.poll_ready() } fn call(&mut self, target: Target) -> Self::Future { @@ -60,19 +57,14 @@ where impl Future for ServiceFuture where S: MakeService, - S::MakeError: Into, - L: Layer, - L::LayerError: Into, + L: Layer, { type Item = L::Service; - type Error = Error; + type Error = S::MakeError; fn poll(&mut self) -> Poll { - let service = try_ready!(self.inner.poll().map_err(Into::into)); - - match self.layer.layer(service) { - Ok(service) => Ok(Async::Ready(service)), - Err(e) => Err(e.into()), - } + let service = try_ready!(self.inner.poll()); + let service = self.layer.layer(service); + Ok(Async::Ready(service)) } } diff --git a/tower/tests/builder.rs b/tower/tests/builder.rs index 9efaabd..156a67f 100644 --- a/tower/tests/builder.rs +++ b/tower/tests/builder.rs @@ -37,8 +37,7 @@ fn builder_service() { .layer(BufferLayer::new(5)) .layer(ConcurrencyLimitLayer::new(5)) .layer(RateLimitLayer::new(5, Duration::from_secs(1))) - .service(MockSvc) - .unwrap(); + .service(MockSvc); client.poll_ready().unwrap(); client