diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c60296707..4b0c6b0bd 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -3,83 +3,60 @@ name: CI on: push: branches: - - master + - master pull_request: {} env: - MSRV: 1.49.0 + MSRV: 1.64.0 jobs: check-stable: # Run `cargo check` first to ensure that the pushed code at least compiles. runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - profile: minimal - override: true - - name: Check - uses: actions-rs/cargo@v1 - with: - command: check - args: --workspace --all-features --all-targets + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - name: Check + run: cargo check --workspace --all-features --all-targets check-docs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - profile: minimal - - name: cargo doc - working-directory: ${{ matrix.subcrate }} - env: - RUSTDOCFLAGS: "-D rustdoc::broken_intra_doc_links" - run: cargo doc --all-features --no-deps + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - name: cargo doc + working-directory: ${{ matrix.subcrate }} + env: + RUSTDOCFLAGS: "-D rustdoc::broken_intra_doc_links" + run: cargo doc --all-features --no-deps check-msrv: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - name: "install Rust ${{ env.MSRV }}" - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ env.MSRV }} - profile: minimal - - name: "install Rust nightly" - uses: actions-rs/toolchain@v1 - with: - toolchain: nightly - profile: minimal - - name: Select minimal versions - uses: actions-rs/cargo@v1 - with: - command: update - args: -Z minimal-versions - toolchain: nightly - - name: Check - uses: actions-rs/cargo@v1 - with: - command: check - args: --all --all-targets --all-features --locked - toolchain: ${{ env.MSRV }} + - uses: actions/checkout@v4 + - name: "install Rust ${{ env.MSRV }}" + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.MSRV }} + - name: "install Rust nightly" + uses: dtolnay/rust-toolchain@nightly + - name: Select minimal versions + run: cargo update -Z minimal-versions + - name: Check + run: | + rustup default ${{ env.MSRV }} + cargo check --all --all-targets --all-features --locked cargo-hack: runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - profile: minimal - - name: install cargo-hack - uses: taiki-e/install-action@cargo-hack - - name: cargo hack check - working-directory: ${{ matrix.subcrate }} - run: cargo hack check --each-feature --no-dev-deps --workspace + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - name: install cargo-hack + uses: taiki-e/install-action@cargo-hack + - name: cargo hack check + working-directory: ${{ matrix.subcrate }} + run: cargo hack check --each-feature --no-dev-deps --workspace test-versions: # Test against the stable, beta, and nightly Rust toolchains on ubuntu-latest. @@ -93,68 +70,48 @@ jobs: matrix: rust: [stable, beta, nightly] steps: - - uses: actions/checkout@master - - name: "install Rust ${{ matrix.rust }}" - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - profile: minimal - override: true - - name: Run tests - uses: actions-rs/cargo@v1 - with: - command: test - args: --workspace --all-features + - uses: actions/checkout@v4 + - name: "install Rust ${{ matrix.rust }}" + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust }} + - name: Run tests + run: cargo test --workspace --all-features test-msrv: needs: check-msrv runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - name: "install Rust ${{ env.MSRV }}" - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ env.MSRV }} - profile: minimal - - name: "install Rust nightly" - uses: actions-rs/toolchain@v1 - with: - toolchain: nightly - profile: minimal - - name: Select minimal versions - uses: actions-rs/cargo@v1 - with: - command: update - args: -Z minimal-versions - toolchain: nightly - - name: test - uses: actions-rs/cargo@v1 - with: - command: check - args: --workspace --all-features --locked - toolchain: ${{ env.MSRV }} + - uses: actions/checkout@v4 + - name: "install Rust ${{ env.MSRV }}" + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.MSRV }} + - name: "install Rust nightly" + uses: dtolnay/rust-toolchain@nightly + - name: Select minimal versions + run: cargo update -Z minimal-versions + - name: test + run: | + rustup default ${{ env.MSRV }} + cargo check --workspace --all-features --locked style: needs: check-stable runs-on: ubuntu-latest steps: - - uses: actions/checkout@master - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: rustfmt - profile: minimal - - name: rustfmt - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + - name: rustfmt + run: cargo fmt --all -- --check deny-check: name: cargo-deny check runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: EmbarkStudios/cargo-deny-action@v1 - with: - command: check + - uses: actions/checkout@v4 + - uses: EmbarkStudios/cargo-deny-action@v1 + with: + command: check diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c499f43bd..7c5e6b909 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,19 +12,13 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v1 + uses: actions/checkout@v4 - name: Install nightly Rust - uses: actions-rs/toolchain@v1 + uses: dtolnay/rust-toolchain@master with: toolchain: nightly - profile: minimal - name: Generate documentation - uses: actions-rs/cargo@v1 - with: - command: doc - args: --workspace --no-deps --all-features - # Tower uses nightly-only RustDoc features - toolchain: nightly + run: cargo doc --workspace --no-deps --all-features env: # Enable the RustDoc `#[doc(cfg(...))]` attribute. RUSTDOCFLAGS: --cfg docsrs @@ -36,4 +30,3 @@ jobs: build_dir: target/doc env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fca0ac1d5..67d6ccdea 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,7 @@ jobs: if: github.repository_owner == 'tower-rs' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: taiki-e/create-gh-release-action@v1.3.0 with: prefix: "(tower)|(tower-[a-z]+)" diff --git a/Cargo.toml b/Cargo.toml index b7d4757b8..bbea40253 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,3 +6,23 @@ members = [ "tower-service", "tower-test", ] + +[workspace.dependencies] +futures = "0.3.22" +futures-core = "0.3.22" +futures-util = { version = "0.3.22", default-features = false } +hdrhistogram = { version = "7.0", default-features = false } +http = "0.2" +indexmap = "2.0.2" +lazy_static = "1.4.0" +pin-project-lite = "0.2.7" +quickcheck = "1" +rand = "0.8" +slab = "0.4" +sync_wrapper = "0.1.1" +tokio = "1.6.2" +tokio-stream = "0.1.0" +tokio-test = "0.4" +tokio-util = { version = "0.7.0", default-features = false } +tracing = { version = "0.1.2", default-features = false } +tracing-subscriber = { version = "0.3", default-features = false } diff --git a/README.md b/README.md index 31a2357a9..c250b1cee 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ pattern. If your protocol is entirely stream based, Tower may not be a good fit. Tower will keep a rolling MSRV (minimum supported Rust version) policy of **at least** 6 months. When increasing the MSRV, the new Rust version must have been -released at least six months ago. The current MSRV is 1.49.0. +released at least six months ago. The current MSRV is 1.64.0. ## Getting Started diff --git a/deny.toml b/deny.toml index 83988ef34..111567196 100644 --- a/deny.toml +++ b/deny.toml @@ -2,7 +2,6 @@ vulnerability = "deny" unmaintained = "warn" notice = "warn" -ignore = ["RUSTSEC-2020-0159"] [licenses] unlicensed = "deny" diff --git a/examples/Cargo.toml b/examples/Cargo.toml index a39ddb9ca..b8faa4622 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -8,11 +8,11 @@ edition = "2018" # [dependencies] instead. [dev-dependencies] tower = { version = "0.4", path = "../tower", features = ["full"] } -tower-service = "0.3" +tower-service = "0.3" tokio = { version = "1.0", features = ["full"] } rand = "0.8" pin-project = "1.0" -futures = "0.3" +futures = "0.3.22" tracing = "0.1" tracing-subscriber = "0.2" hdrhistogram = "7" diff --git a/guides/building-a-middleware-from-scratch.md b/guides/building-a-middleware-from-scratch.md index d6a008148..95c06e984 100644 --- a/guides/building-a-middleware-from-scratch.md +++ b/guides/building-a-middleware-from-scratch.md @@ -390,7 +390,7 @@ means we can combine multiple errors type into one. That has the following advantages: 1. Our error handling is less fragile since changing the order middleware are - applied in wont change the final error type. + applied in won't change the final error type. 2. The error type now has a constant size regardless how many middleware we've applied. 3. Extracting the error no longer requires a big `match` but can instead be done @@ -412,7 +412,7 @@ For our `Timeout` middleware that means we need to create a struct that implements `std::error::Error` such that we can convert it into a `Box`. We also have to require that the inner service's error type implements `Into>`. Luckily most errors automatically satisfies that so it wont require +Sync>>`. Luckily most errors automatically satisfies that so it won't require users to write any additional code. We're using `Into` for the trait bound rather than `From` as recommend by the [standard library](https://doc.rust-lang.org/stable/std/convert/trait.From.html). @@ -521,7 +521,7 @@ where ## Conclusion -Thats it! We've now successfully implemented the `Timeout` middleware as it +That's it! We've now successfully implemented the `Timeout` middleware as it exists in Tower today. Our final implementation is: diff --git a/tower-layer/src/identity.rs b/tower-layer/src/identity.rs index 5ce805bd1..5233a1d81 100644 --- a/tower-layer/src/identity.rs +++ b/tower-layer/src/identity.rs @@ -14,7 +14,7 @@ pub struct Identity { impl Identity { /// Create a new [`Identity`] value - pub fn new() -> Identity { + pub const fn new() -> Identity { Identity { _p: () } } } diff --git a/tower-layer/src/stack.rs b/tower-layer/src/stack.rs index cc0b826e9..cb6bac7b7 100644 --- a/tower-layer/src/stack.rs +++ b/tower-layer/src/stack.rs @@ -10,7 +10,7 @@ pub struct Stack { impl Stack { /// Create a new `Stack`. - pub fn new(inner: Inner, outer: Outer) -> Self { + pub const fn new(inner: Inner, outer: Outer) -> Self { Stack { inner, outer } } } diff --git a/tower-service/Cargo.toml b/tower-service/Cargo.toml index 68a5a8768..0e6f5b25a 100644 --- a/tower-service/Cargo.toml +++ b/tower-service/Cargo.toml @@ -22,7 +22,7 @@ edition = "2018" [dependencies] [dev-dependencies] -http = "0.2" +http = { workspace = true } tower-layer = { version = "0.3", path = "../tower-layer" } -tokio = { version = "1", features = ["macros", "time"] } -futures = "0.3" +tokio = { workspace = true, features = ["macros", "time"] } +futures = { workspace = true } diff --git a/tower-service/src/lib.rs b/tower-service/src/lib.rs index d3ddd20f4..58cc2eb1c 100644 --- a/tower-service/src/lib.rs +++ b/tower-service/src/lib.rs @@ -130,7 +130,7 @@ use std::task::{Context, Poll}; /// } /// /// impl Timeout { -/// pub fn new(inner: T, timeout: Duration) -> Timeout { +/// pub const fn new(inner: T, timeout: Duration) -> Timeout { /// Timeout { /// inner, /// timeout @@ -204,7 +204,7 @@ use std::task::{Context, Poll}; /// pub struct TimeoutLayer(Duration); /// /// impl TimeoutLayer { -/// pub fn new(delay: Duration) -> Self { +/// pub const fn new(delay: Duration) -> Self { /// TimeoutLayer(delay) /// } /// } diff --git a/tower-test/Cargo.toml b/tower-test/Cargo.toml index 2c01cae21..fad3cd5b4 100644 --- a/tower-test/Cargo.toml +++ b/tower-test/Cargo.toml @@ -20,12 +20,12 @@ categories = ["asynchronous", "network-programming"] edition = "2018" [dependencies] -futures-util = { version = "0.3", default-features = false } -tokio = { version = "1.0", features = ["sync"] } -tokio-test = "0.4" +futures-util = { workspace = true } +tokio = { workspace = true, features = ["sync"] } +tokio-test = { workspace = true } tower-layer = { version = "0.3", path = "../tower-layer" } tower-service = { version = "0.3", path = "../tower-service" } -pin-project-lite = "0.2" +pin-project-lite = { workspace = true } [dev-dependencies] -tokio = { version = "1.0", features = ["macros"] } +tokio = { workspace = true, features = ["macros"] } diff --git a/tower/Cargo.toml b/tower/Cargo.toml index 96269dc80..4529d8ce3 100644 --- a/tower/Cargo.toml +++ b/tower/Cargo.toml @@ -20,7 +20,7 @@ clients and servers. categories = ["asynchronous", "network-programming"] keywords = ["io", "async", "non-blocking", "futures", "service"] edition = "2018" -rust-version = "1.49.0" +rust-version = "1.64.0" [features] @@ -68,32 +68,32 @@ util = ["__common", "futures-util", "pin-project-lite", "sync_wrapper"] tower-layer = { version = "0.3.1", path = "../tower-layer" } tower-service = { version = "0.3.1", path = "../tower-service" } -futures-core = { version = "0.3", optional = true } -futures-util = { version = "0.3", default-features = false, features = ["alloc"], optional = true } -hdrhistogram = { version = "7.0", optional = true, default-features = false } -indexmap = { version = "1.0.2", optional = true } -slab = { version = "0.4", optional = true } -tokio = { version = "1.6", optional = true, features = ["sync"] } -tokio-stream = { version = "0.1.0", optional = true } -tokio-util = { version = "0.7.0", default-features = false, optional = true } -tracing = { version = "0.1.2", default-features = false, features = ["std"], optional = true } -pin-project-lite = { version = "0.2.7", optional = true } -sync_wrapper = { version = "0.1.1", optional = true } +futures-core = { workspace = true, optional = true } +futures-util = { workspace = true, features = ["alloc"], optional = true } +hdrhistogram = { workspace = true, optional = true } +indexmap = { workspace = true, optional = true } +slab = { workspace = true, optional = true } +tokio = { workspace = true, features = ["sync"], optional = true } +tokio-stream = { workspace = true, optional = true } +tokio-util = { workspace = true, optional = true } +tracing = { workspace = true, features = ["std"], optional = true } +pin-project-lite = { workspace = true, optional = true } +sync_wrapper = { workspace = true, optional = true } [dev-dependencies] -futures = "0.3" -hdrhistogram = { version = "7.0", default-features = false } -pin-project-lite = "0.2.7" -tokio = { version = "1.6.2", features = ["macros", "sync", "test-util", "rt-multi-thread"] } -tokio-stream = "0.1" -tokio-test = "0.4" +futures = { workspace = true } +hdrhistogram = { workspace = true } +pin-project-lite = { workspace = true } +tokio = { workspace = true, features = ["macros", "sync", "test-util", "rt-multi-thread"] } +tokio-stream = { workspace = true } +tokio-test = { workspace = true } tower-test = { version = "0.4", path = "../tower-test" } -tracing = { version = "0.1.2", default-features = false, features = ["std"] } -tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt", "ansi"] } -http = "0.2" -lazy_static = "1.4.0" -rand = { version = "0.8", features = ["small_rng"] } -quickcheck = "1" +tracing = { workspace = true, features = ["std"] } +tracing-subscriber = { workspace = true, features = ["fmt", "ansi"] } +http = { workspace = true } +lazy_static = { workspace = true } +rand = { workspace = true, features = ["small_rng"] } +quickcheck = { workspace = true } [package.metadata.docs.rs] all-features = true diff --git a/tower/README.md b/tower/README.md index f5bc7d01e..f5d196d7b 100644 --- a/tower/README.md +++ b/tower/README.md @@ -74,7 +74,7 @@ application code, libraries providing middleware implementations, and libraries that implement servers and/or clients for various network protocols. -Depending on your particular use case, you might use Tower in several ways: +Depending on your particular use case, you might use Tower in several ways: * **Implementing application logic** for a networked program. You might use the [`Service`] trait to model your application's behavior, and use @@ -174,7 +174,7 @@ Tower. Tower will keep a rolling MSRV (minimum supported Rust version) policy of **at least** 6 months. When increasing the MSRV, the new Rust version must have been -released at least six months ago. The current MSRV is 1.49.0. +released at least six months ago. The current MSRV is 1.64.0. ## License diff --git a/tower/src/balance/p2c/layer.rs b/tower/src/balance/p2c/layer.rs index ce59c6e06..6a2032c04 100644 --- a/tower/src/balance/p2c/layer.rs +++ b/tower/src/balance/p2c/layer.rs @@ -24,7 +24,7 @@ pub struct MakeBalanceLayer { impl MakeBalanceLayer { /// Build balancers using operating system entropy. - pub fn new() -> Self { + pub const fn new() -> Self { Self { _marker: PhantomData, } diff --git a/tower/src/balance/p2c/make.rs b/tower/src/balance/p2c/make.rs index 538d70360..45a35d1b4 100644 --- a/tower/src/balance/p2c/make.rs +++ b/tower/src/balance/p2c/make.rs @@ -42,7 +42,7 @@ pin_project! { impl MakeBalance { /// Build balancers using operating system entropy. - pub fn new(make_discover: S) -> Self { + pub const fn new(make_discover: S) -> Self { Self { inner: make_discover, _marker: PhantomData, diff --git a/tower/src/balance/p2c/mod.rs b/tower/src/balance/p2c/mod.rs index 0d4203cc1..8925e41b8 100644 --- a/tower/src/balance/p2c/mod.rs +++ b/tower/src/balance/p2c/mod.rs @@ -23,7 +23,7 @@ //! Since the load balancer needs to perform _random_ choices, the constructors in this module //! usually come in two forms: one that uses randomness provided by the operating system, and one //! that lets you specify the random seed to use. Usually the former is what you'll want, though -//! the latter may come in handy for reproducability or to reduce reliance on the operating system. +//! the latter may come in handy for reproducibility or to reduce reliance on the operating system. //! //! [Power of Two Random Choices]: http://www.eecs.harvard.edu/~michaelm/postscripts/handbook2001.pdf //! [finagle]: https://twitter.github.io/finagle/guide/Clients.html#power-of-two-choices-p2c-least-loaded diff --git a/tower/src/buffer/layer.rs b/tower/src/buffer/layer.rs index 8ef916714..3fc26ab59 100644 --- a/tower/src/buffer/layer.rs +++ b/tower/src/buffer/layer.rs @@ -33,7 +33,7 @@ impl BufferLayer { /// [`Poll::Ready`]: std::task::Poll::Ready /// [`call`]: crate::Service::call /// [`poll_ready`]: crate::Service::poll_ready - pub fn new(bound: usize) -> Self { + pub const fn new(bound: usize) -> Self { BufferLayer { bound, _p: PhantomData, diff --git a/tower/src/builder/mod.rs b/tower/src/builder/mod.rs index 5518b00bc..74134ac58 100644 --- a/tower/src/builder/mod.rs +++ b/tower/src/builder/mod.rs @@ -115,7 +115,7 @@ impl Default for ServiceBuilder { impl ServiceBuilder { /// Create a new [`ServiceBuilder`]. - pub fn new() -> Self { + pub const fn new() -> Self { ServiceBuilder { layer: Identity::new(), } diff --git a/tower/src/filter/layer.rs b/tower/src/filter/layer.rs index 4ca634449..30cbcdeca 100644 --- a/tower/src/filter/layer.rs +++ b/tower/src/filter/layer.rs @@ -35,7 +35,7 @@ impl FilterLayer { /// /// [`Predicate`]: crate::filter::Predicate /// [`Filter`]: crate::filter::Filter - pub fn new(predicate: U) -> Self { + pub const fn new(predicate: U) -> Self { Self { predicate } } } @@ -57,7 +57,7 @@ impl AsyncFilterLayer { /// /// [`AsyncPredicate`]: crate::filter::AsyncPredicate /// [`Filter`]: crate::filter::Filter - pub fn new(predicate: U) -> Self { + pub const fn new(predicate: U) -> Self { Self { predicate } } } diff --git a/tower/src/filter/mod.rs b/tower/src/filter/mod.rs index b7c05cf6a..c53ba404f 100644 --- a/tower/src/filter/mod.rs +++ b/tower/src/filter/mod.rs @@ -61,7 +61,7 @@ pub struct AsyncFilter { impl Filter { /// Returns a new [`Filter`] service wrapping `inner`. - pub fn new(inner: T, predicate: U) -> Self { + pub const fn new(inner: T, predicate: U) -> Self { Self { inner, predicate } } @@ -123,7 +123,7 @@ where impl AsyncFilter { /// Returns a new [`AsyncFilter`] service wrapping `inner`. - pub fn new(inner: T, predicate: U) -> Self { + pub const fn new(inner: T, predicate: U) -> Self { Self { inner, predicate } } diff --git a/tower/src/hedge/delay.rs b/tower/src/hedge/delay.rs index 3d634bfaa..7b45c0eff 100644 --- a/tower/src/hedge/delay.rs +++ b/tower/src/hedge/delay.rs @@ -62,7 +62,7 @@ impl State { } impl Delay { - pub fn new(policy: P, service: S) -> Self + pub const fn new(policy: P, service: S) -> Self where P: Policy, S: Service + Clone, diff --git a/tower/src/hedge/latency.rs b/tower/src/hedge/latency.rs index b1a8b2459..723652aaa 100644 --- a/tower/src/hedge/latency.rs +++ b/tower/src/hedge/latency.rs @@ -38,7 +38,7 @@ impl Latency where R: Record + Clone, { - pub fn new(rec: R, service: S) -> Self + pub const fn new(rec: R, service: S) -> Self where S: Service, S::Error: Into, diff --git a/tower/src/hedge/select.rs b/tower/src/hedge/select.rs index 5d1573c08..e9f2660d5 100644 --- a/tower/src/hedge/select.rs +++ b/tower/src/hedge/select.rs @@ -34,7 +34,7 @@ pin_project! { } impl Select { - pub fn new(policy: P, a: A, b: B) -> Self + pub const fn new(policy: P, a: A, b: B) -> Self where P: Policy, A: Service, diff --git a/tower/src/lib.rs b/tower/src/lib.rs index 073fd016f..179edfbec 100644 --- a/tower/src/lib.rs +++ b/tower/src/lib.rs @@ -22,7 +22,7 @@ //! response or an error. This abstraction can be used to model both clients and //! servers. //! -//! Generic components, like [timeouts], [rate limiting], and [load balancing], +//! Generic components, like [`timeout`], [rate limiting], and [load balancing], //! can be modeled as [`Service`]s that wrap some inner service and apply //! additional behavior before or after the inner service is called. This allows //! implementing these components in a protocol-agnostic, composable way. Typically, @@ -130,7 +130,7 @@ //! ``` //! //! Alternatively, you can only enable some features. For example, to enable -//! only the [`retry`] and [`timeout`][timeouts] middleware, write: +//! only the [`retry`] and [`timeout`] middleware, write: //! //! ```toml //! tower = { version = "0.4", features = ["retry", "timeout"] } @@ -144,11 +144,10 @@ //! //! Tower will keep a rolling MSRV (minimum supported Rust version) policy of **at //! least** 6 months. When increasing the MSRV, the new Rust version must have been -//! released at least six months ago. The current MSRV is 1.49.0. +//! released at least six months ago. The current MSRV is 1.64.0. //! //! [`Service`]: crate::Service //! [`Layer`]: crate::Layer -//! [timeouts]: crate::timeout //! [rate limiting]: crate::limit::rate //! [load balancing]: crate::balance //! [`ServiceBuilder`]: crate::ServiceBuilder @@ -202,15 +201,20 @@ pub mod layer; #[cfg(feature = "util")] #[doc(inline)] +#[cfg_attr(docsrs, doc(cfg(feature = "util")))] pub use self::util::{service_fn, ServiceExt}; #[doc(inline)] pub use crate::builder::ServiceBuilder; + #[cfg(feature = "make")] #[doc(inline)] +#[cfg_attr(docsrs, doc(cfg(feature = "make")))] pub use crate::make::MakeService; + #[doc(inline)] pub use tower_layer::Layer; + #[doc(inline)] pub use tower_service::Service; diff --git a/tower/src/limit/concurrency/layer.rs b/tower/src/limit/concurrency/layer.rs index 1966d5785..30257c457 100644 --- a/tower/src/limit/concurrency/layer.rs +++ b/tower/src/limit/concurrency/layer.rs @@ -13,7 +13,7 @@ pub struct ConcurrencyLimitLayer { impl ConcurrencyLimitLayer { /// Create a new concurrency limit layer. - pub fn new(max: usize) -> Self { + pub const fn new(max: usize) -> Self { ConcurrencyLimitLayer { max } } } diff --git a/tower/src/limit/rate/layer.rs b/tower/src/limit/rate/layer.rs index 9051ddd08..5f8d31aaf 100644 --- a/tower/src/limit/rate/layer.rs +++ b/tower/src/limit/rate/layer.rs @@ -11,7 +11,7 @@ pub struct RateLimitLayer { impl RateLimitLayer { /// Create new rate limit layer. - pub fn new(num: u64, per: Duration) -> Self { + pub const fn new(num: u64, per: Duration) -> Self { let rate = Rate::new(num, per); RateLimitLayer { rate } } diff --git a/tower/src/limit/rate/rate.rs b/tower/src/limit/rate/rate.rs index d0736f427..66736deaa 100644 --- a/tower/src/limit/rate/rate.rs +++ b/tower/src/limit/rate/rate.rs @@ -13,9 +13,9 @@ impl Rate { /// # Panics /// /// This function panics if `num` or `per` is 0. - pub fn new(num: u64, per: Duration) -> Self { + pub const fn new(num: u64, per: Duration) -> Self { assert!(num > 0); - assert!(per > Duration::from_millis(0)); + assert!(per.as_nanos() > 0); Rate { num, per } } diff --git a/tower/src/load/completion.rs b/tower/src/load/completion.rs index 3c14a7ff7..857e05536 100644 --- a/tower/src/load/completion.rs +++ b/tower/src/load/completion.rs @@ -59,7 +59,7 @@ pin_project! { impl TrackCompletionFuture { /// Wraps a future, propagating the tracker into its value if successful. - pub fn new(completion: C, handle: H, future: F) -> Self { + pub const fn new(completion: C, handle: H, future: F) -> Self { TrackCompletionFuture { future, completion, diff --git a/tower/src/load/constant.rs b/tower/src/load/constant.rs index f05182f85..b53a10bf5 100644 --- a/tower/src/load/constant.rs +++ b/tower/src/load/constant.rs @@ -27,7 +27,7 @@ pin_project! { impl Constant { /// Wraps a `T`-typed service with a constant `M`-typed load metric. - pub fn new(inner: T, load: M) -> Self { + pub const fn new(inner: T, load: M) -> Self { Self { inner, load } } } diff --git a/tower/src/load/pending_requests.rs b/tower/src/load/pending_requests.rs index 3d8689bbe..2721633fd 100644 --- a/tower/src/load/pending_requests.rs +++ b/tower/src/load/pending_requests.rs @@ -45,6 +45,7 @@ pub struct Count(usize); /// Tracks an in-flight request by reference count. #[derive(Debug)] +#[allow(dead_code)] pub struct Handle(RefCount); // ===== impl PendingRequests ===== @@ -100,7 +101,7 @@ where #[cfg(feature = "discover")] impl PendingRequestsDiscover { /// Wraps a [`Discover`], wrapping all of its services with [`PendingRequests`]. - pub fn new(discover: D, completion: C) -> Self + pub const fn new(discover: D, completion: C) -> Self where D: Discover, D::Service: Service, diff --git a/tower/src/load_shed/error.rs b/tower/src/load_shed/error.rs index 3a4c025b4..e11da5825 100644 --- a/tower/src/load_shed/error.rs +++ b/tower/src/load_shed/error.rs @@ -14,7 +14,7 @@ pub struct Overloaded { impl Overloaded { /// Construct a new overloaded error - pub fn new() -> Self { + pub const fn new() -> Self { Overloaded { _p: () } } } diff --git a/tower/src/load_shed/layer.rs b/tower/src/load_shed/layer.rs index 65ab29f14..5585db796 100644 --- a/tower/src/load_shed/layer.rs +++ b/tower/src/load_shed/layer.rs @@ -13,7 +13,7 @@ pub struct LoadShedLayer { impl LoadShedLayer { /// Creates a new layer. - pub fn new() -> Self { + pub const fn new() -> Self { LoadShedLayer { _p: () } } } diff --git a/tower/src/load_shed/mod.rs b/tower/src/load_shed/mod.rs index deadf0fcb..422f30880 100644 --- a/tower/src/load_shed/mod.rs +++ b/tower/src/load_shed/mod.rs @@ -23,7 +23,7 @@ pub struct LoadShed { impl LoadShed { /// Wraps a service in [`LoadShed`] middleware. - pub fn new(inner: S) -> Self { + pub const fn new(inner: S) -> Self { LoadShed { inner, is_ready: false, diff --git a/tower/src/make/make_service/shared.rs b/tower/src/make/make_service/shared.rs index fd308a02a..2b2bc0265 100644 --- a/tower/src/make/make_service/shared.rs +++ b/tower/src/make/make_service/shared.rs @@ -75,7 +75,7 @@ pub struct Shared { impl Shared { /// Create a new [`Shared`] from a service. - pub fn new(service: S) -> Self { + pub const fn new(service: S) -> Self { Self { service } } } diff --git a/tower/src/ready_cache/cache.rs b/tower/src/ready_cache/cache.rs index 282f2bb83..b3aec3781 100644 --- a/tower/src/ready_cache/cache.rs +++ b/tower/src/ready_cache/cache.rs @@ -31,7 +31,7 @@ use tracing::{debug, trace}; /// in the ready set. The `ReadyCache::check_*` functions can be used to ensure /// that a service is ready before dispatching a request. /// -/// The ready set can hold services for an abitrarily long time. During this +/// The ready set can hold services for an arbitrarily long time. During this /// time, the runtime may process events that invalidate that ready state (for /// instance, if a keepalive detects a lost connection). In such cases, callers /// should use [`ReadyCache::check_ready`] (or [`ReadyCache::check_ready_index`]) @@ -193,7 +193,7 @@ where } /// Obtains a mutable reference to a service in the ready set by index. - pub fn get_ready_index_mut(&mut self, idx: usize) -> Option<(&mut K, &mut S)> { + pub fn get_ready_index_mut(&mut self, idx: usize) -> Option<(&K, &mut S)> { self.ready.get_index_mut(idx).map(|(k, v)| (k, &mut v.0)) } diff --git a/tower/src/reconnect/mod.rs b/tower/src/reconnect/mod.rs index ff354821c..0062fe398 100644 --- a/tower/src/reconnect/mod.rs +++ b/tower/src/reconnect/mod.rs @@ -49,7 +49,7 @@ where M: Service, { /// Lazily connect and reconnect to a [`Service`]. - pub fn new(mk_service: M, target: Target) -> Self { + pub const fn new(mk_service: M, target: Target) -> Self { Reconnect { mk_service, state: State::Idle, @@ -59,7 +59,7 @@ where } /// Reconnect to a already connected [`Service`]. - pub fn with_connection(init_conn: M::Response, mk_service: M, target: Target) -> Self { + pub const fn with_connection(init_conn: M::Response, mk_service: M, target: Target) -> Self { Reconnect { mk_service, state: State::Connected(init_conn), diff --git a/tower/src/retry/backoff.rs b/tower/src/retry/backoff.rs index 306723eda..685063ec3 100644 --- a/tower/src/retry/backoff.rs +++ b/tower/src/retry/backoff.rs @@ -1,4 +1,4 @@ -//! This module contains generic [backoff] utlities to be used with the retry +//! This module contains generic [backoff] utilities to be used with the retry //! layer. //! //! The [`Backoff`] trait is a generic way to represent backoffs that can use diff --git a/tower/src/retry/budget/tps_budget.rs b/tower/src/retry/budget/tps_budget.rs index 3f1d530bc..d6949980b 100644 --- a/tower/src/retry/budget/tps_budget.rs +++ b/tower/src/retry/budget/tps_budget.rs @@ -31,7 +31,7 @@ pub struct TpsBudget { slots: Box<[AtomicIsize]>, /// The amount of time represented by each slot. window: Duration, - /// The changers for the current slot to be commited + /// The changers for the current slot to be committed /// after the slot expires. writer: AtomicIsize, /// Amount of tokens to deposit for each put(). diff --git a/tower/src/retry/layer.rs b/tower/src/retry/layer.rs index 830348582..f7f2c640b 100644 --- a/tower/src/retry/layer.rs +++ b/tower/src/retry/layer.rs @@ -9,7 +9,7 @@ pub struct RetryLayer

{ impl

RetryLayer

{ /// Creates a new [`RetryLayer`] from a retry policy. - pub fn new(policy: P) -> Self { + pub const fn new(policy: P) -> Self { RetryLayer { policy } } } diff --git a/tower/src/retry/mod.rs b/tower/src/retry/mod.rs index 3abd94fca..1bb5e29ed 100644 --- a/tower/src/retry/mod.rs +++ b/tower/src/retry/mod.rs @@ -49,7 +49,7 @@ pin_project! { impl Retry { /// Retry the inner service depending on this [`Policy`]. - pub fn new(policy: P, service: S) -> Self { + pub const fn new(policy: P, service: S) -> Self { Retry { policy, service } } diff --git a/tower/src/spawn_ready/service.rs b/tower/src/spawn_ready/service.rs index 7e6ea7920..d9573f50e 100644 --- a/tower/src/spawn_ready/service.rs +++ b/tower/src/spawn_ready/service.rs @@ -26,7 +26,7 @@ enum Inner { impl SpawnReady { /// Creates a new [`SpawnReady`] wrapping `service`. - pub fn new(service: S) -> Self { + pub const fn new(service: S) -> Self { Self { inner: Inner::Service(Some(service)), } diff --git a/tower/src/steer/mod.rs b/tower/src/steer/mod.rs index 3483c928b..d6141965c 100644 --- a/tower/src/steer/mod.rs +++ b/tower/src/steer/mod.rs @@ -91,7 +91,7 @@ where /// /// An example use case is a sharded service. /// It accepts new requests, then: -/// 1. Determines, via the provided [`Picker`], which [`Service`] the request coresponds to. +/// 1. Determines, via the provided [`Picker`], which [`Service`] the request corresponds to. /// 2. Waits (in [`Service::poll_ready`]) for *all* services to be ready. /// 3. Calls the correct [`Service`] with the request, and returns a future corresponding to the /// call. diff --git a/tower/src/timeout/error.rs b/tower/src/timeout/error.rs index 223cada68..cc309b9c6 100644 --- a/tower/src/timeout/error.rs +++ b/tower/src/timeout/error.rs @@ -8,7 +8,7 @@ pub struct Elapsed(pub(super) ()); impl Elapsed { /// Construct a new elapsed error - pub fn new() -> Self { + pub const fn new() -> Self { Elapsed(()) } } diff --git a/tower/src/timeout/layer.rs b/tower/src/timeout/layer.rs index 3397fd85f..d8cc2d1c2 100644 --- a/tower/src/timeout/layer.rs +++ b/tower/src/timeout/layer.rs @@ -10,7 +10,7 @@ pub struct TimeoutLayer { impl TimeoutLayer { /// Create a timeout from a duration - pub fn new(timeout: Duration) -> Self { + pub const fn new(timeout: Duration) -> Self { TimeoutLayer { timeout } } } diff --git a/tower/src/timeout/mod.rs b/tower/src/timeout/mod.rs index 0e65a3f65..da3bbf98d 100644 --- a/tower/src/timeout/mod.rs +++ b/tower/src/timeout/mod.rs @@ -25,7 +25,7 @@ pub struct Timeout { impl Timeout { /// Creates a new [`Timeout`] - pub fn new(inner: T, timeout: Duration) -> Self { + pub const fn new(inner: T, timeout: Duration) -> Self { Timeout { inner, timeout } } diff --git a/tower/src/util/and_then.rs b/tower/src/util/and_then.rs index 819ca273c..adb9ada79 100644 --- a/tower/src/util/and_then.rs +++ b/tower/src/util/and_then.rs @@ -74,7 +74,7 @@ pub struct AndThenLayer { impl AndThen { /// Creates a new `AndThen` service. - pub fn new(inner: S, f: F) -> Self { + pub const fn new(inner: S, f: F) -> Self { AndThen { f, inner } } @@ -110,7 +110,7 @@ where impl AndThenLayer { /// Creates a new [`AndThenLayer`] layer. - pub fn new(f: F) -> Self { + pub const fn new(f: F) -> Self { AndThenLayer { f } } } diff --git a/tower/src/util/call_all/common.rs b/tower/src/util/call_all/common.rs index a4963473a..3b3f8938c 100644 --- a/tower/src/util/call_all/common.rs +++ b/tower/src/util/call_all/common.rs @@ -51,7 +51,7 @@ where S: Stream, Q: Drive, { - pub(crate) fn new(service: Svc, stream: S, queue: Q) -> CallAll { + pub(crate) const fn new(service: Svc, stream: S, queue: Q) -> CallAll { CallAll { service: Some(service), stream, diff --git a/tower/src/util/call_all/ordered.rs b/tower/src/util/call_all/ordered.rs index cf55c2214..9a283916b 100644 --- a/tower/src/util/call_all/ordered.rs +++ b/tower/src/util/call_all/ordered.rs @@ -63,7 +63,7 @@ pin_project! { /// reqs.unbounded_send("three").unwrap(); /// drop(reqs); /// - /// // We then loop over the response Strem that we get back from call_all. + /// // We then loop over the response `Stream` that we get back from call_all. /// let mut i = 0usize; /// while let Some(rsp) = rsps.next().await { /// // Each response is a Result (we could also have used TryStream::try_next) @@ -168,7 +168,7 @@ impl common::Drive for FuturesOrdered { } fn push(&mut self, future: F) { - FuturesOrdered::push(self, future) + FuturesOrdered::push_back(self, future) } fn poll(&mut self, cx: &mut Context<'_>) -> Poll> { diff --git a/tower/src/util/future_service.rs b/tower/src/util/future_service.rs index ef3a74914..c0a36df25 100644 --- a/tower/src/util/future_service.rs +++ b/tower/src/util/future_service.rs @@ -101,7 +101,7 @@ impl FutureService { /// /// This will most likely come up if you're calling `future_service` with an async block. In that /// case you can use `Box::pin(async { ... })` as shown in the example. - pub fn new(future: F) -> Self { + pub const fn new(future: F) -> Self { Self { state: State::Future(future), } diff --git a/tower/src/util/map_err.rs b/tower/src/util/map_err.rs index b79c5fee2..1b936acbc 100644 --- a/tower/src/util/map_err.rs +++ b/tower/src/util/map_err.rs @@ -42,7 +42,7 @@ opaque_future! { impl MapErr { /// Creates a new [`MapErr`] service. - pub fn new(inner: S, f: F) -> Self { + pub const fn new(inner: S, f: F) -> Self { MapErr { f, inner } } @@ -78,7 +78,7 @@ where impl MapErrLayer { /// Creates a new [`MapErrLayer`]. - pub fn new(f: F) -> Self { + pub const fn new(f: F) -> Self { MapErrLayer { f } } } diff --git a/tower/src/util/map_future.rs b/tower/src/util/map_future.rs index 9f5670add..55bf96d07 100644 --- a/tower/src/util/map_future.rs +++ b/tower/src/util/map_future.rs @@ -17,7 +17,7 @@ pub struct MapFuture { impl MapFuture { /// Creates a new [`MapFuture`] service. - pub fn new(inner: S, f: F) -> Self { + pub const fn new(inner: S, f: F) -> Self { Self { inner, f } } @@ -88,7 +88,7 @@ pub struct MapFutureLayer { impl MapFutureLayer { /// Creates a new [`MapFutureLayer`] layer. - pub fn new(f: F) -> Self { + pub const fn new(f: F) -> Self { Self { f } } } diff --git a/tower/src/util/map_request.rs b/tower/src/util/map_request.rs index e86e0680b..62f2de3cb 100644 --- a/tower/src/util/map_request.rs +++ b/tower/src/util/map_request.rs @@ -26,7 +26,7 @@ where impl MapRequest { /// Creates a new [`MapRequest`] service. - pub fn new(inner: S, f: F) -> Self { + pub const fn new(inner: S, f: F) -> Self { MapRequest { inner, f } } @@ -70,7 +70,7 @@ pub struct MapRequestLayer { impl MapRequestLayer { /// Creates a new [`MapRequestLayer`]. - pub fn new(f: F) -> Self { + pub const fn new(f: F) -> Self { MapRequestLayer { f } } } diff --git a/tower/src/util/map_response.rs b/tower/src/util/map_response.rs index 249be3a4d..8edac10aa 100644 --- a/tower/src/util/map_response.rs +++ b/tower/src/util/map_response.rs @@ -42,7 +42,7 @@ opaque_future! { impl MapResponse { /// Creates a new `MapResponse` service. - pub fn new(inner: S, f: F) -> Self { + pub const fn new(inner: S, f: F) -> Self { MapResponse { f, inner } } @@ -78,7 +78,7 @@ where impl MapResponseLayer { /// Creates a new [`MapResponseLayer`] layer. - pub fn new(f: F) -> Self { + pub const fn new(f: F) -> Self { MapResponseLayer { f } } } diff --git a/tower/src/util/map_result.rs b/tower/src/util/map_result.rs index bfe16b5b4..5a96af2d1 100644 --- a/tower/src/util/map_result.rs +++ b/tower/src/util/map_result.rs @@ -42,7 +42,7 @@ opaque_future! { impl MapResult { /// Creates a new [`MapResult`] service. - pub fn new(inner: S, f: F) -> Self { + pub const fn new(inner: S, f: F) -> Self { MapResult { f, inner } } @@ -79,7 +79,7 @@ where impl MapResultLayer { /// Creates a new [`MapResultLayer`] layer. - pub fn new(f: F) -> Self { + pub const fn new(f: F) -> Self { MapResultLayer { f } } } diff --git a/tower/src/util/oneshot.rs b/tower/src/util/oneshot.rs index 93b5070be..114b2f825 100644 --- a/tower/src/util/oneshot.rs +++ b/tower/src/util/oneshot.rs @@ -35,11 +35,11 @@ pin_project! { } impl, Req> State { - fn not_ready(svc: S, req: Option) -> Self { + const fn not_ready(svc: S, req: Option) -> Self { Self::NotReady { svc, req } } - fn called(fut: S::Future) -> Self { + const fn called(fut: S::Future) -> Self { Self::Called { fut } } } @@ -71,7 +71,7 @@ where S: Service, { #[allow(missing_docs)] - pub fn new(svc: S, req: Req) -> Self { + pub const fn new(svc: S, req: Req) -> Self { Oneshot { state: State::not_ready(svc, Some(req)), } diff --git a/tower/src/util/optional/mod.rs b/tower/src/util/optional/mod.rs index 8ba3ab95d..4d0207093 100644 --- a/tower/src/util/optional/mod.rs +++ b/tower/src/util/optional/mod.rs @@ -23,7 +23,7 @@ pub struct Optional { impl Optional { /// Create a new [`Optional`]. - pub fn new(inner: Option) -> Optional + pub const fn new(inner: Option) -> Optional where T: Service, T::Error: Into, diff --git a/tower/src/util/ready.rs b/tower/src/util/ready.rs index 668d50143..750db872f 100644 --- a/tower/src/util/ready.rs +++ b/tower/src/util/ready.rs @@ -26,7 +26,7 @@ where T: Service, { #[allow(missing_docs)] - pub fn new(service: T) -> Self { + pub const fn new(service: T) -> Self { Self { inner: Some(service), _p: PhantomData, diff --git a/tower/src/util/rng.rs b/tower/src/util/rng.rs index d520ffce6..9b6d307d9 100644 --- a/tower/src/util/rng.rs +++ b/tower/src/util/rng.rs @@ -3,7 +3,7 @@ //! This module provides a generic [`Rng`] trait and a [`HasherRng`] that //! implements the trait based on [`RandomState`] or any other [`Hasher`]. //! -//! These utlities replace tower's internal usage of `rand` with these smaller, +//! These utilities replace tower's internal usage of `rand` with these smaller, //! more lightweight methods. Most of the implementations are extracted from //! their corresponding `rand` implementations. //! @@ -27,11 +27,11 @@ pub trait Rng { // Borrowed from: // https://github.com/rust-random/rand/blob/master/src/distributions/float.rs#L106 let float_size = std::mem::size_of::() as u32 * 8; - let precison = 52 + 1; - let scale = 1.0 / ((1u64 << precison) as f64); + let precision = 52 + 1; + let scale = 1.0 / ((1u64 << precision) as f64); let value = self.next_u64(); - let value = value >> (float_size - precison); + let value = value >> (float_size - precision); scale * value as f64 } @@ -111,8 +111,8 @@ where /// A sampler modified from the Rand implementation for use internally for the balance middleware. /// -/// It's an implemenetation of Floyd's combination algorithm. with amount fixed at 2. This uses no allocated -/// memory and finishes in constant time (only 2 random calls) +/// It's an implementation of Floyd's combination algorithm with amount fixed at 2. This uses no allocated +/// memory and finishes in constant time (only 2 random calls). /// /// ref: This was borrowed and modified from the following Rand implementation /// https://github.com/rust-random/rand/blob/b73640705d6714509f8ceccc49e8df996fa19f51/src/seq/index.rs#L375-L411 @@ -174,7 +174,7 @@ mod tests { let mut r = HasherRng::default(); match super::sample_floyd2(&mut r, 2) { [0, 1] | [1, 0] => (), - err => panic!("{err:?}"), + array => panic!("unexpected inplace boundaries: {:?}", array), } } } diff --git a/tower/src/util/then.rs b/tower/src/util/then.rs index 1ec3c1492..5e9345067 100644 --- a/tower/src/util/then.rs +++ b/tower/src/util/then.rs @@ -38,7 +38,7 @@ pub struct ThenLayer { impl Then { /// Creates a new `Then` service. - pub fn new(inner: S, f: F) -> Self { + pub const fn new(inner: S, f: F) -> Self { Then { f, inner } } @@ -83,7 +83,7 @@ where impl ThenLayer { /// Creates a new [`ThenLayer`] layer. - pub fn new(f: F) -> Self { + pub const fn new(f: F) -> Self { ThenLayer { f } } } diff --git a/tower/tests/ready_cache/main.rs b/tower/tests/ready_cache/main.rs index 56be6a9cb..cdcfcbbf9 100644 --- a/tower/tests/ready_cache/main.rs +++ b/tower/tests/ready_cache/main.rs @@ -200,7 +200,7 @@ async fn cancelation_observed() { let mut handles = vec![]; // NOTE This test passes at 129 items, but fails at 130 items (if coop - // schedulding interferes with cancelation). + // scheduling interferes with cancelation). for _ in 0..130 { let (svc, mut handle) = tower_test::mock::pair::<(), ()>(); handle.allow(1);