Consistently apply deny/warn rules (#352)
This makes all tower subcrates have the following lints as warn (rather than allow): `missing_docs`, `rust_2018_idioms`, `unreachable_pub`, and `missing_debug_implementations`. In addition, it consistently applies `deny(warning)` *only* under CI so that deprecations and macro changes in minor version bumps in dependencies will never cause `tower` crates to stop compiling, and so that tests can be run even if not all warnings have been dealt with. See also https://github.com/rust-unofficial/patterns/blob/master/anti_patterns/deny-warnings.md Note that `tower-reconnect` has the `missing_docs` lint disabled for now since it contained _no_ documentation previously. Also note that this patch does not add documentation to the various `new` methods, as they are considered self-explanatory. They are instead marked as `#[allow(missing_docs)]`.
This commit is contained in:
parent
5a561b7776
commit
6baf381879
|
@ -17,6 +17,7 @@ jobs:
|
|||
- script: cargo test
|
||||
env:
|
||||
CI: 'True'
|
||||
RUSTFLAGS: '-D warnings'
|
||||
displayName: cargo test -p ${{ crate }}
|
||||
workingDirectory: $(Build.SourcesDirectory)/${{ crate }}
|
||||
condition: and(succeeded(), ne(variables['isRelease'], 'true'))
|
||||
|
@ -27,5 +28,6 @@ jobs:
|
|||
- script: cargo test
|
||||
env:
|
||||
CI: 'True'
|
||||
RUSTFLAGS: '-D warnings'
|
||||
displayName: cargo test -p ${{ crate }}
|
||||
workingDirectory: $(Build.SourcesDirectory)/${{ crate }}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
//! Load balancing middlewares.
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/tower-balance/0.3.0-alpha.1")]
|
||||
#![deny(missing_docs)]
|
||||
#![deny(rust_2018_idioms)]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
#![allow(elided_lifetimes_in_paths)]
|
||||
#![deny(warnings)]
|
||||
|
||||
pub mod error;
|
||||
pub mod p2c;
|
||||
|
|
|
@ -19,8 +19,9 @@ pub struct BalanceMake<S, Req> {
|
|||
_marker: PhantomData<fn(Req)>,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
/// Makes a balancer instance.
|
||||
#[pin_project]
|
||||
#[derive(Debug)]
|
||||
pub struct MakeFuture<F, Req> {
|
||||
#[pin]
|
||||
inner: F,
|
||||
|
|
|
@ -6,6 +6,7 @@ use pin_project::pin_project;
|
|||
use rand::{rngs::SmallRng, FromEntropy};
|
||||
use std::marker::PhantomData;
|
||||
use std::{
|
||||
fmt,
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
|
@ -36,7 +37,6 @@ use tracing::{debug, trace};
|
|||
/// [p2c]: http://www.eecs.harvard.edu/~michaelm/postscripts/handbook2001.pdf
|
||||
/// [`Box::pin`]: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.pin
|
||||
/// [#319]: https://github.com/tower-rs/tower/issues/319
|
||||
#[derive(Debug)]
|
||||
pub struct Balance<D: Discover, Req> {
|
||||
discover: D,
|
||||
|
||||
|
@ -54,6 +54,23 @@ pub struct Balance<D: Discover, Req> {
|
|||
_req: PhantomData<Req>,
|
||||
}
|
||||
|
||||
impl<D: Discover, Req> fmt::Debug for Balance<D, Req>
|
||||
where
|
||||
D: fmt::Debug,
|
||||
D::Key: fmt::Debug,
|
||||
D::Service: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Balance")
|
||||
.field("discover", &self.discover)
|
||||
.field("ready_services", &self.ready_services)
|
||||
.field("unready_services", &self.unready_services)
|
||||
.field("cancelations", &self.cancelations)
|
||||
.field("next_ready_index", &self.next_ready_index)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
/// A Future that becomes satisfied when an `S`-typed service is ready.
|
||||
///
|
||||
|
|
|
@ -20,6 +20,7 @@ use futures_core::ready;
|
|||
use pin_project::pin_project;
|
||||
use slab::Slab;
|
||||
use std::{
|
||||
fmt,
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
|
@ -42,9 +43,9 @@ enum Level {
|
|||
High,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
/// A wrapper around `MakeService` that discovers a new service when load is high, and removes a
|
||||
/// service when load is low. See [`Pool`].
|
||||
#[pin_project]
|
||||
pub struct PoolDiscoverer<MS, Target, Request>
|
||||
where
|
||||
MS: MakeService<Target, Request>,
|
||||
|
@ -61,6 +62,23 @@ where
|
|||
limit: Option<usize>,
|
||||
}
|
||||
|
||||
impl<MS, Target, Request> fmt::Debug for PoolDiscoverer<MS, Target, Request>
|
||||
where
|
||||
MS: MakeService<Target, Request> + fmt::Debug,
|
||||
Target: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("PoolDiscoverer")
|
||||
.field("maker", &self.maker)
|
||||
.field("making", &self.making.is_some())
|
||||
.field("target", &self.target)
|
||||
.field("load", &self.load)
|
||||
.field("services", &self.services)
|
||||
.field("limit", &self.limit)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<MS, Target, Request> Discover for PoolDiscoverer<MS, Target, Request>
|
||||
where
|
||||
MS: MakeService<Target, Request>,
|
||||
|
@ -298,6 +316,23 @@ where
|
|||
ewma: f64,
|
||||
}
|
||||
|
||||
impl<MS, Target, Request> fmt::Debug for Pool<MS, Target, Request>
|
||||
where
|
||||
MS: MakeService<Target, Request> + fmt::Debug,
|
||||
MS::MakeError: Into<error::Error>,
|
||||
MS::Error: Into<error::Error>,
|
||||
Target: Clone + fmt::Debug,
|
||||
MS::Service: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Pool")
|
||||
.field("balance", &self.balance)
|
||||
.field("options", &self.options)
|
||||
.field("ewma", &self.ewma)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<MS, Target, Request> Pool<MS, Target, Request>
|
||||
where
|
||||
MS: MakeService<Target, Request>,
|
||||
|
@ -396,6 +431,7 @@ where
|
|||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[derive(Debug)]
|
||||
pub struct DropNotifyService<Svc> {
|
||||
svc: Svc,
|
||||
id: usize,
|
||||
|
|
|
@ -14,12 +14,14 @@ use std::{
|
|||
|
||||
/// Future eventually completed with the response to the original request.
|
||||
#[pin_project]
|
||||
#[derive(Debug)]
|
||||
pub struct ResponseFuture<T> {
|
||||
#[pin]
|
||||
state: ResponseState<T>,
|
||||
}
|
||||
|
||||
#[pin_project]
|
||||
#[derive(Debug)]
|
||||
enum ResponseState<T> {
|
||||
Failed(Option<Error>),
|
||||
Rx(#[pin] message::Rx<T>),
|
||||
|
|
|
@ -12,6 +12,7 @@ pub struct BufferLayer<Request, E = DefaultExecutor> {
|
|||
}
|
||||
|
||||
impl<Request> BufferLayer<Request, DefaultExecutor> {
|
||||
#[allow(missing_docs)]
|
||||
pub fn new(bound: usize) -> Self {
|
||||
BufferLayer {
|
||||
bound,
|
||||
|
@ -22,6 +23,7 @@ impl<Request> BufferLayer<Request, DefaultExecutor> {
|
|||
}
|
||||
|
||||
impl<Request, E: Clone> BufferLayer<Request, E> {
|
||||
/// Create a new buffered service layer spawned on the given executor.
|
||||
pub fn with_executor(bound: usize, executor: E) -> Self {
|
||||
BufferLayer {
|
||||
bound,
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
#![doc(html_root_url = "https://docs.rs/tower-buffer/0.3.0-alpha.1a")]
|
||||
#![deny(rust_2018_idioms)]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
#![allow(elided_lifetimes_in_paths)]
|
||||
|
||||
//! Buffer requests when the inner service is out of capacity.
|
||||
|
|
|
@ -14,6 +14,7 @@ use tower_service::Service;
|
|||
/// Adds a buffer in front of an inner service.
|
||||
///
|
||||
/// See crate level documentation for more details.
|
||||
#[derive(Debug)]
|
||||
pub struct Buffer<T, Request>
|
||||
where
|
||||
T: Service<Request>,
|
||||
|
|
|
@ -22,6 +22,7 @@ use tower_service::Service;
|
|||
/// types in public traits that are not meant for consumers of the library to
|
||||
/// implement (only call).
|
||||
#[pin_project]
|
||||
#[derive(Debug)]
|
||||
pub struct Worker<T, Request>
|
||||
where
|
||||
T: Service<Request>,
|
||||
|
@ -36,6 +37,7 @@ where
|
|||
}
|
||||
|
||||
/// Get the error out
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Handle {
|
||||
inner: Arc<Mutex<Option<ServiceError>>>,
|
||||
}
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
#![doc(html_root_url = "https://docs.rs/tower-discover/0.3.0-alpha.1")]
|
||||
#![deny(rust_2018_idioms)]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
#![allow(elided_lifetimes_in_paths)]
|
||||
|
||||
//! # Tower service discovery
|
||||
|
@ -32,6 +37,7 @@ pub trait Discover {
|
|||
/// NewService key
|
||||
type Key: Hash + Eq;
|
||||
|
||||
/// The type of `Service` yielded by this `Discover`.
|
||||
type Service;
|
||||
|
||||
/// Error produced during discovery
|
||||
|
@ -88,7 +94,10 @@ impl<D: ?Sized + Discover + Unpin> Discover for Box<D> {
|
|||
}
|
||||
|
||||
/// A change in the service set
|
||||
#[derive(Debug)]
|
||||
pub enum Change<K, V> {
|
||||
/// A new service identified by key `K` was identified.
|
||||
Insert(K, V),
|
||||
/// The service identified by key `K` disappeared.
|
||||
Remove(K),
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ use tower_service::Service;
|
|||
/// `ServiceList` is created with an initial list of services. The discovery
|
||||
/// process will yield this list once and do nothing after.
|
||||
#[pin_project]
|
||||
#[derive(Debug)]
|
||||
pub struct ServiceList<T>
|
||||
where
|
||||
T: IntoIterator,
|
||||
|
@ -23,6 +24,7 @@ impl<T, U> ServiceList<T>
|
|||
where
|
||||
T: IntoIterator<Item = U>,
|
||||
{
|
||||
#[allow(missing_docs)]
|
||||
pub fn new<Request>(services: T) -> ServiceList<T>
|
||||
where
|
||||
U: Service<Request>,
|
||||
|
|
|
@ -10,12 +10,14 @@ use tower_service::Service;
|
|||
|
||||
/// Dynamic service discovery based on a stream of service changes.
|
||||
#[pin_project]
|
||||
#[derive(Debug)]
|
||||
pub struct ServiceStream<S> {
|
||||
#[pin]
|
||||
inner: S,
|
||||
}
|
||||
|
||||
impl<S> ServiceStream<S> {
|
||||
#[allow(missing_docs)]
|
||||
pub fn new<K, Svc, Request>(services: S) -> Self
|
||||
where
|
||||
S: TryStream<Ok = Change<K, Svc>>,
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
use crate::Filter;
|
||||
use tower_layer::Layer;
|
||||
|
||||
/// Conditionally dispatch requests to the inner service based on a predicate.
|
||||
#[derive(Debug)]
|
||||
pub struct FilterLayer<U> {
|
||||
predicate: U,
|
||||
}
|
||||
|
||||
impl<U> FilterLayer<U> {
|
||||
#[allow(missing_docs)]
|
||||
pub fn new(predicate: U) -> Self {
|
||||
FilterLayer { predicate }
|
||||
}
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
#![doc(html_root_url = "https://docs.rs/tower-filter/0.3.0-alpha.1")]
|
||||
#![deny(rust_2018_idioms)]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
#![allow(elided_lifetimes_in_paths)]
|
||||
|
||||
//! Conditionally dispatch requests to the inner service based on the result of
|
||||
|
@ -17,6 +22,7 @@ use futures_core::ready;
|
|||
use std::task::{Context, Poll};
|
||||
use tower_service::Service;
|
||||
|
||||
/// Conditionally dispatch requests to the inner service based on a predicate.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Filter<T, U> {
|
||||
inner: T,
|
||||
|
@ -24,6 +30,7 @@ pub struct Filter<T, U> {
|
|||
}
|
||||
|
||||
impl<T, U> Filter<T, U> {
|
||||
#[allow(missing_docs)]
|
||||
pub fn new(inner: T, predicate: U) -> Self {
|
||||
Filter { inner, predicate }
|
||||
}
|
||||
|
|
|
@ -3,8 +3,12 @@ use std::future::Future;
|
|||
|
||||
/// Checks a request
|
||||
pub trait Predicate<Request> {
|
||||
/// The future returned by `check`.
|
||||
type Future: Future<Output = Result<(), Error>>;
|
||||
|
||||
/// Check whether the given request should be forwarded.
|
||||
///
|
||||
/// If the future resolves with `Ok`, the request is forwarded to the inner service.
|
||||
fn check(&mut self, request: &Request) -> Self::Future;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
//! Pre-emptively retry requests which have been outstanding for longer
|
||||
//! than a given latency percentile.
|
||||
|
||||
#![deny(warnings)]
|
||||
#![deny(missing_docs)]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
|
||||
use futures_util::future;
|
||||
use log::error;
|
||||
|
@ -37,8 +41,9 @@ type Service<S, P> = select::Select<
|
|||
#[derive(Debug)]
|
||||
pub struct Hedge<S, P>(Service<S, P>);
|
||||
|
||||
#[pin_project]
|
||||
/// The Future returned by the hedge Service.
|
||||
#[pin_project]
|
||||
#[derive(Debug)]
|
||||
pub struct Future<S, Request>
|
||||
where
|
||||
S: tower_service::Service<Request>,
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
extern crate tokio_timer;
|
||||
|
||||
use hdrhistogram::Histogram;
|
||||
use log::trace;
|
||||
use std::time::{Duration, Instant};
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
#![doc(html_root_url = "https://docs.rs/tower-layer/0.3.0-alpha.1")]
|
||||
#![deny(missing_docs, rust_2018_idioms)]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
|
||||
//! Layer traits and extensions.
|
||||
//!
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#![doc(html_root_url = "https://docs.rs/tower-limit/0.3.0-alpha.1")]
|
||||
#![cfg_attr(test, deny(warnings))]
|
||||
#![deny(missing_debug_implementations, missing_docs, rust_2018_idioms)]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
#![allow(elided_lifetimes_in_paths)]
|
||||
|
||||
//! Tower middleware for limiting requests.
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#![doc(html_root_url = "https://docs.rs/tower-load-shed/0.3.0-alpha.1")]
|
||||
#![cfg_attr(test, deny(warnings))]
|
||||
#![deny(missing_debug_implementations, missing_docs, rust_2018_idioms)]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
#![allow(elided_lifetimes_in_paths)]
|
||||
|
||||
//! Tower middleware for shedding load when inner services aren't ready.
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
//! Abstractions and utilties for measuring a service's load.
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/tower-load/0.3.0-alpha.1")]
|
||||
#![deny(missing_docs)]
|
||||
#![deny(rust_2018_idioms)]
|
||||
#![deny(warnings)]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
#![allow(elided_lifetimes_in_paths)]
|
||||
|
||||
mod constant;
|
||||
|
|
|
@ -42,6 +42,7 @@ use tower_service::Service;
|
|||
///
|
||||
/// [finagle]:
|
||||
/// https://github.com/twitter/finagle/blob/9cc08d15216497bb03a1cafda96b7266cfbbcff1/finagle-core/src/main/scala/com/twitter/finagle/loadbalancer/PeakEwma.scala
|
||||
#[derive(Debug)]
|
||||
pub struct PeakEwma<S, I = NoInstrument> {
|
||||
service: S,
|
||||
decay_ns: f64,
|
||||
|
@ -51,6 +52,7 @@ pub struct PeakEwma<S, I = NoInstrument> {
|
|||
|
||||
/// Wraps a `D`-typed stream of discovery updates with `PeakEwma`.
|
||||
#[pin_project]
|
||||
#[derive(Debug)]
|
||||
pub struct PeakEwmaDiscover<D, I = NoInstrument> {
|
||||
#[pin]
|
||||
discover: D,
|
||||
|
@ -67,6 +69,7 @@ pub struct PeakEwmaDiscover<D, I = NoInstrument> {
|
|||
pub struct Cost(f64);
|
||||
|
||||
/// Tracks an in-flight request and updates the RTT-estimate on Drop.
|
||||
#[derive(Debug)]
|
||||
pub struct Handle {
|
||||
sent_at: Instant,
|
||||
decay_ns: f64,
|
||||
|
@ -74,6 +77,7 @@ pub struct Handle {
|
|||
}
|
||||
|
||||
/// Holds the current RTT estimate and the last time this value was updated.
|
||||
#[derive(Debug)]
|
||||
struct RttEstimate {
|
||||
update_at: Instant,
|
||||
rtt_ns: f64,
|
||||
|
|
|
@ -135,7 +135,7 @@ where
|
|||
// ==== RefCount ====
|
||||
|
||||
impl RefCount {
|
||||
pub fn ref_count(&self) -> usize {
|
||||
pub(crate) fn ref_count(&self) -> usize {
|
||||
Arc::strong_count(&self.0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
#![doc(html_root_url = "https://docs.rs/tower-make/0.3.0-alpha.2")]
|
||||
#![deny(rust_2018_idioms)]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
|
||||
//! Trait aliases for Services that produce specific types of Responses.
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ use std::{
|
|||
};
|
||||
|
||||
#[pin_project]
|
||||
#[derive(Debug)]
|
||||
pub struct ResponseFuture<F> {
|
||||
#[pin]
|
||||
inner: F,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#![doc(html_root_url = "https://docs.rs/tower-reconnect/0.3.0-alpha.1")]
|
||||
#![deny(rust_2018_idioms)]
|
||||
#![warn(missing_debug_implementations, rust_2018_idioms, unreachable_pub)]
|
||||
#![allow(missing_docs)] // TODO
|
||||
#![allow(elided_lifetimes_in_paths)]
|
||||
|
||||
pub mod future;
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#![doc(html_root_url = "https://docs.rs/tower-retry/0.3.0-alpha.1")]
|
||||
#![deny(missing_docs, missing_debug_implementations, rust_2018_idioms)]
|
||||
#![cfg_attr(test, deny(warnings))]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
#![allow(elided_lifetimes_in_paths)]
|
||||
|
||||
//! Tower middleware for retrying "failed" requests.
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
#![deny(missing_docs)]
|
||||
#![doc(html_root_url = "https://docs.rs/tower-service/0.3.0-alpha.1")]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
|
||||
//! Definition of the core `Service` trait to Tower
|
||||
//!
|
||||
|
|
|
@ -13,8 +13,9 @@ use tokio_executor::TypedExecutor;
|
|||
use tokio_sync::oneshot;
|
||||
use tower_service::Service;
|
||||
|
||||
#[pin_project]
|
||||
/// Drives a service to readiness.
|
||||
#[pin_project]
|
||||
#[derive(Debug)]
|
||||
pub struct BackgroundReady<T, Request> {
|
||||
service: Option<T>,
|
||||
tx: Option<oneshot::Sender<Result<T, Error>>>,
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
#![doc(html_root_url = "https://docs.rs/tower-spawn-ready/0.3.0-alpha.1")]
|
||||
#![deny(missing_docs, rust_2018_idioms, warnings)]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
#![allow(elided_lifetimes_in_paths)]
|
||||
|
||||
//! When an underlying service is not ready, drive it to readiness on a
|
||||
|
|
|
@ -16,10 +16,12 @@ use tower_service::Service;
|
|||
/// Spawns tasks to drive an inner service to readiness.
|
||||
///
|
||||
/// See crate level documentation for more details.
|
||||
#[derive(Debug)]
|
||||
pub struct SpawnReady<T> {
|
||||
inner: Inner<T>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Inner<T> {
|
||||
Service(Option<T>),
|
||||
Future(oneshot::Receiver<Result<T, Error>>),
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
#![doc(html_root_url = "https://docs.rs/tower-test/0.3.0-alpha.1")]
|
||||
#![deny(rust_2018_idioms)]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
#![allow(elided_lifetimes_in_paths)]
|
||||
|
||||
//! Mock `Service` that can be used in tests.
|
||||
|
|
|
@ -4,6 +4,7 @@ use std::{error, fmt};
|
|||
|
||||
pub(crate) type Error = Box<dyn error::Error + Send + Sync>;
|
||||
|
||||
/// Error yielded when a mocked service does not yet accept requests.
|
||||
#[derive(Debug)]
|
||||
pub struct Closed(());
|
||||
|
||||
|
|
|
@ -261,11 +261,13 @@ impl<T, U> Drop for Handle<T, U> {
|
|||
// ===== impl SendResponse =====
|
||||
|
||||
impl<T> SendResponse<T> {
|
||||
/// Resolve the pending request future for the linked request with the given response.
|
||||
pub fn send_response(self, response: T) {
|
||||
// TODO: Should the result be dropped?
|
||||
let _ = self.tx.send(Ok(response));
|
||||
}
|
||||
|
||||
/// Resolve the pending request future for the linked request with the given error.
|
||||
pub fn send_error<E: Into<Error>>(self, err: E) {
|
||||
// TODO: Should the result be dropped?
|
||||
let _ = self.tx.send(Err(err.into()));
|
||||
|
|
|
@ -16,7 +16,7 @@ impl Elapsed {
|
|||
}
|
||||
|
||||
impl fmt::Display for Elapsed {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.pad("request timed out")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#![doc(html_root_url = "https://docs.rs/tower-timeout/0.3.0-alpha.1")]
|
||||
#![deny(missing_debug_implementations, missing_docs, rust_2018_idioms)]
|
||||
#![allow(elided_lifetimes_in_paths)]
|
||||
#![cfg_attr(test, deny(warnings))]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
|
||||
//! Tower middleware that applies a timeout to requests.
|
||||
//!
|
||||
|
|
|
@ -32,4 +32,5 @@
|
|||
mod sync;
|
||||
mod unsync;
|
||||
|
||||
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
|
||||
pub use self::{sync::BoxService, unsync::UnsyncBoxService};
|
||||
|
|
|
@ -30,6 +30,7 @@ struct Boxed<S> {
|
|||
}
|
||||
|
||||
impl<T, U, E> BoxService<T, U, E> {
|
||||
#[allow(missing_docs)]
|
||||
pub fn new<S>(inner: S) -> Self
|
||||
where
|
||||
S: Service<T, Response = U, Error = E> + Send + 'static,
|
||||
|
|
|
@ -24,6 +24,7 @@ struct UnsyncBoxed<S> {
|
|||
}
|
||||
|
||||
impl<T, U, E> UnsyncBoxService<T, U, E> {
|
||||
#[allow(missing_docs)]
|
||||
pub fn new<S>(inner: S) -> Self
|
||||
where
|
||||
S: Service<T, Response = U, Error = E> + 'static,
|
||||
|
|
|
@ -4,6 +4,7 @@ mod common;
|
|||
mod ordered;
|
||||
mod unordered;
|
||||
|
||||
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
|
||||
pub use self::{ordered::CallAll, unordered::CallAllUnordered};
|
||||
|
||||
type Error = Box<dyn std::error::Error + Send + Sync>;
|
||||
|
|
|
@ -19,7 +19,9 @@ use tower_service::Service;
|
|||
#[pin_project]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Either<A, B> {
|
||||
/// One type of backing `Service`.
|
||||
A(#[pin] A),
|
||||
/// The other type of backing `Service`.
|
||||
B(#[pin] B),
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
#![doc(html_root_url = "https://docs.rs/tower-util/0.3.0-alpha.1")]
|
||||
#![deny(rust_2018_idioms)]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
#![allow(elided_lifetimes_in_paths)]
|
||||
|
||||
//! Various utility types and functions that are generally with Tower.
|
||||
|
@ -7,13 +12,15 @@
|
|||
mod boxed;
|
||||
mod call_all;
|
||||
mod either;
|
||||
pub mod layer;
|
||||
mod oneshot;
|
||||
mod optional;
|
||||
mod ready;
|
||||
mod sealed;
|
||||
mod service_fn;
|
||||
|
||||
/// Different ways to chain service layers.
|
||||
pub mod layer;
|
||||
|
||||
pub use crate::{
|
||||
boxed::{BoxService, UnsyncBoxService},
|
||||
call_all::{CallAll, CallAllUnordered},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use futures_util::ready;
|
||||
use pin_project::{pin_project, project};
|
||||
use std::{
|
||||
fmt,
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
|
@ -11,6 +12,7 @@ use tower_service::Service;
|
|||
/// is ready, and then calling `Service::call` with the request, and
|
||||
/// waiting for that `Future`.
|
||||
#[pin_project]
|
||||
#[derive(Debug)]
|
||||
pub struct Oneshot<S: Service<Req>, Req> {
|
||||
#[pin]
|
||||
state: State<S, Req>,
|
||||
|
@ -23,10 +25,30 @@ enum State<S: Service<Req>, Req> {
|
|||
Done,
|
||||
}
|
||||
|
||||
impl<S, Req> fmt::Debug for State<S, Req>
|
||||
where
|
||||
S: Service<Req> + fmt::Debug,
|
||||
Req: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
State::NotReady(Some((s, req))) => f
|
||||
.debug_tuple("State::NotReady")
|
||||
.field(s)
|
||||
.field(req)
|
||||
.finish(),
|
||||
State::NotReady(None) => unreachable!(),
|
||||
State::Called(_) => f.debug_tuple("State::Called").field(&"S::Future").finish(),
|
||||
State::Done => f.debug_tuple("State::Done").finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, Req> Oneshot<S, Req>
|
||||
where
|
||||
S: Service<Req>,
|
||||
{
|
||||
#[allow(missing_docs)]
|
||||
pub fn new(svc: S, req: Req) -> Self {
|
||||
Oneshot {
|
||||
state: State::NotReady(Some((svc, req))),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::{error, fmt};
|
||||
|
||||
/// Error returned if the inner `Service` has not been set.
|
||||
#[derive(Debug)]
|
||||
pub struct None(());
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ use std::{
|
|||
|
||||
/// Response future returned by `Optional`.
|
||||
#[pin_project]
|
||||
#[derive(Debug)]
|
||||
pub struct ResponseFuture<T> {
|
||||
#[pin]
|
||||
inner: Option<T>,
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
//! See `OptionService` documentation for more details.
|
||||
//!
|
||||
|
||||
/// Error types for `OptionalService`.
|
||||
pub mod error;
|
||||
/// Future types for `OptionalService`.
|
||||
pub mod future;
|
||||
|
||||
use self::{error::Error, future::ResponseFuture};
|
||||
|
@ -13,6 +15,7 @@ use tower_service::Service;
|
|||
/// Optionally forwards requests to an inner service.
|
||||
///
|
||||
/// If the inner service is `None`, `Error::None` is returned as the response.
|
||||
#[derive(Debug)]
|
||||
pub struct Optional<T> {
|
||||
inner: Option<T>,
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ impl<'a, T, Request> Ready<'a, T, Request>
|
|||
where
|
||||
T: Service<Request>,
|
||||
{
|
||||
#[allow(missing_docs)]
|
||||
pub fn new(service: &'a mut T) -> Self {
|
||||
Ready {
|
||||
inner: service,
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
#[allow(unreachable_pub)]
|
||||
pub trait Sealed<T> {}
|
||||
|
|
|
@ -188,7 +188,7 @@ impl<L> ServiceBuilder<L> {
|
|||
}
|
||||
|
||||
impl<L: fmt::Debug> fmt::Debug for ServiceBuilder<L> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_tuple("ServiceBuilder").field(&self.layer).finish()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
// Allows refining features in the future without breaking backwards
|
||||
// compatibility
|
||||
#![cfg(feature = "full")]
|
||||
#![deny(missing_docs, missing_debug_implementations, rust_2018_idioms)]
|
||||
#![allow(elided_lifetimes_in_paths)]
|
||||
#![cfg_attr(test, deny(warnings))]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
|
||||
//! `fn(Request) -> Future<Response>`
|
||||
//!
|
||||
|
|
Loading…
Reference in New Issue