From 68e44fa9dabe055b885a49da4db0c9ea288b266c Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Tue, 26 Oct 2021 00:08:59 +0200 Subject: [PATCH] Vendor `AddExtensionLayer` and `AddExtension` (#414) This remove tower-http from axum's public API. I would like to be able to make breaking releases of tower-http without also having to ship a breaking release of axum. --- CHANGELOG.md | 2 ++ src/add_extension.rs | 70 +++++++++++++++++++++++++++++++++++++ src/extract/connect_info.rs | 5 +-- src/lib.rs | 4 +-- 4 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 src/add_extension.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 718d9139..e314e93a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 public because `Router` is internally boxed ([#404]) - **breaking:** Remove `routing::Layered` as it didn't actually do anything and thus wasn't necessary + - **breaking:** Vendor `AddExtensionLayer` and `AddExtension` to reduce public + dependencies - Routing: - Big internal refactoring of routing leading to several improvements ([#363]) - **added:** Wildcard routes like `.route("/api/users/*rest", service)` are now supported. diff --git a/src/add_extension.rs b/src/add_extension.rs new file mode 100644 index 00000000..24e12b24 --- /dev/null +++ b/src/add_extension.rs @@ -0,0 +1,70 @@ +// this is vendored from tower-http to reduce public dependencies + +use http::Request; +use std::task::{Context, Poll}; +use tower_layer::Layer; +use tower_service::Service; + +/// [`Layer`] for adding some shareable value to [request extensions]. +/// +/// See [Sharing state with handlers](index.html#sharing-state-with-handlers) +/// for more details. +/// +/// [request extensions]: https://docs.rs/http/latest/http/struct.Extensions.html +#[derive(Clone, Copy, Debug)] +pub struct AddExtensionLayer { + value: T, +} + +impl AddExtensionLayer { + /// Create a new [`AddExtensionLayer`]. + pub fn new(value: T) -> Self { + AddExtensionLayer { value } + } +} + +impl Layer for AddExtensionLayer +where + T: Clone, +{ + type Service = AddExtension; + + fn layer(&self, inner: S) -> Self::Service { + AddExtension { + inner, + value: self.value.clone(), + } + } +} + +/// Middleware for adding some shareable value to [request extensions]. +/// +/// See [Sharing state with handlers](index.html#sharing-state-with-handlers) +/// for more details. +/// +/// [request extensions]: https://docs.rs/http/latest/http/struct.Extensions.html +#[derive(Clone, Copy, Debug)] +pub struct AddExtension { + inner: S, + value: T, +} + +impl Service> for AddExtension +where + S: Service>, + T: Clone + Send + Sync + 'static, +{ + type Response = S::Response; + type Error = S::Error; + type Future = S::Future; + + #[inline] + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, mut req: Request) -> Self::Future { + req.extensions_mut().insert(self.value.clone()); + self.inner.call(req) + } +} diff --git a/src/extract/connect_info.rs b/src/extract/connect_info.rs index ba51a9cc..3b804900 100644 --- a/src/extract/connect_info.rs +++ b/src/extract/connect_info.rs @@ -5,6 +5,7 @@ //! [`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info use super::{Extension, FromRequest, RequestParts}; +use crate::{AddExtension, AddExtensionLayer}; use async_trait::async_trait; use hyper::server::conn::AddrStream; use std::future::ready; @@ -15,7 +16,7 @@ use std::{ net::SocketAddr, task::{Context, Poll}, }; -use tower_http::add_extension::AddExtension; +use tower_layer::Layer; use tower_service::Service; /// A [`MakeService`] created from a router. @@ -91,7 +92,7 @@ where fn call(&mut self, target: T) -> Self::Future { let connect_info = ConnectInfo(C::connect_info(target)); - let svc = AddExtension::new(self.svc.clone(), connect_info); + let svc = AddExtensionLayer::new(connect_info).layer(self.svc.clone()); ResponseFuture { future: ready(Ok(svc)), } diff --git a/src/lib.rs b/src/lib.rs index f21b681e..0dc1ca3b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1238,6 +1238,7 @@ #[macro_use] pub(crate) mod macros; +mod add_extension; mod clone_box_service; mod error; #[cfg(feature = "json")] @@ -1254,14 +1255,13 @@ pub mod routing; #[cfg(test)] mod tests; +pub use add_extension::{AddExtension, AddExtensionLayer}; #[doc(no_inline)] pub use async_trait::async_trait; #[doc(no_inline)] pub use http; #[doc(no_inline)] pub use hyper::Server; -#[doc(no_inline)] -pub use tower_http::add_extension::{AddExtension, AddExtensionLayer}; #[doc(inline)] #[cfg(feature = "json")]