diff --git a/tower-buffer/src/layer.rs b/tower-buffer/src/layer.rs index 10c4f5c..009d3be 100644 --- a/tower-buffer/src/layer.rs +++ b/tower-buffer/src/layer.rs @@ -1,5 +1,5 @@ use crate::{error::Error, service::Buffer, worker::WorkerExecutor}; -use std::marker::PhantomData; +use std::{fmt, marker::PhantomData}; use tokio_executor::DefaultExecutor; use tower_layer::Layer; use tower_service::Service; @@ -43,3 +43,15 @@ where Buffer::with_executor(service, self.bound, &mut self.executor.clone()) } } + +impl fmt::Debug for BufferLayer +where + // Require E: Debug in case we want to print the executor at a later date + E: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("BufferLayer") + .field("bound", &self.bound) + .finish() + } +} diff --git a/tower-load-shed/src/layer.rs b/tower-load-shed/src/layer.rs index 7b578d0..3a2f0fb 100644 --- a/tower-load-shed/src/layer.rs +++ b/tower-load-shed/src/layer.rs @@ -1,9 +1,10 @@ +use std::fmt; use tower_layer::Layer; use crate::LoadShed; /// A `tower-layer` to wrap services in `LoadShed` middleware. -#[derive(Debug)] +#[derive(Clone)] pub struct LoadShedLayer { _p: (), } @@ -22,3 +23,9 @@ impl Layer for LoadShedLayer { LoadShed::new(service) } } + +impl fmt::Debug for LoadShedLayer { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("LoadShedLayer").finish() + } +} diff --git a/tower-util/src/layer/identity.rs b/tower-util/src/layer/identity.rs index e56c9c8..ccdf4eb 100644 --- a/tower-util/src/layer/identity.rs +++ b/tower-util/src/layer/identity.rs @@ -1,10 +1,11 @@ +use std::fmt; use tower_layer::Layer; /// A no-op middleware. /// /// When wrapping a `Service`, the `Identity` layer returns the provided /// service without modifying it. -#[derive(Debug, Default, Clone)] +#[derive(Default, Clone)] pub struct Identity { _p: (), } @@ -24,3 +25,9 @@ impl Layer for Identity { inner } } + +impl fmt::Debug for Identity { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Identity").finish() + } +} diff --git a/tower-util/src/layer/stack.rs b/tower-util/src/layer/stack.rs index b71b1c4..191c75c 100644 --- a/tower-util/src/layer/stack.rs +++ b/tower-util/src/layer/stack.rs @@ -1,9 +1,8 @@ +use std::fmt; use tower_layer::Layer; /// Two middlewares chained together. -/// -/// This type is produced by `Layer::chain`. -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct Stack { inner: Inner, outer: Outer, @@ -29,3 +28,35 @@ where self.outer.layer(inner) } } + +impl fmt::Debug for Stack +where + Inner: fmt::Debug, + Outer: fmt::Debug, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // The generated output of nested `Stack`s is very noisy and makes + // it harder to understand what is in a `ServiceBuilder`. + // + // Instead, this output is designed assuming that a `Stack` is + // usually quite nested, and inside a `ServiceBuilder`. Therefore, + // this skips using `f.debug_struct()`, since each one would force + // a new layer of indentation. + // + // - In compact mode, a nested stack ends up just looking like a flat + // list of layers. + // + // - In pretty mode, while a newline is inserted between each layer, + // the `DebugStruct` used in the `ServiceBuilder` will inject padding + // to that each line is at the same indentation level. + // + // Also, the order of [outer, inner] is important, since it reflects + // the order that the layers were added to the stack. + if f.alternate() { + // pretty + write!(f, "{:#?},\n{:#?}", self.outer, self.inner) + } else { + write!(f, "{:?}, {:?}", self.outer, self.inner) + } + } +} diff --git a/tower/src/builder/mod.rs b/tower/src/builder/mod.rs index 55154bb..62f617c 100644 --- a/tower/src/builder/mod.rs +++ b/tower/src/builder/mod.rs @@ -11,7 +11,7 @@ use crate::{ use tower_layer::Layer; use tower_util::layer::{Identity, Stack}; -use std::time::Duration; +use std::{fmt, time::Duration}; /// Declaratively construct Service values. /// @@ -142,7 +142,7 @@ use std::time::Duration; /// .rate_limit(5, Duration::from_secs(1)) /// .service(MyService); /// ``` -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct ServiceBuilder { layer: L, } @@ -220,3 +220,9 @@ impl ServiceBuilder { self.layer.layer(service) } } + +impl fmt::Debug for ServiceBuilder { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_tuple("ServiceBuilder").field(&self.layer).finish() + } +} diff --git a/tower/src/lib.rs b/tower/src/lib.rs index ccb6aa5..14430ab 100644 --- a/tower/src/lib.rs +++ b/tower/src/lib.rs @@ -3,6 +3,7 @@ // compatibility #![cfg(feature = "full")] #![deny(missing_docs, missing_debug_implementations, rust_2018_idioms)] +#![allow(elided_lifetimes_in_paths)] #![cfg_attr(test, deny(warnings))] //! `fn(Request) -> Future`