diff --git a/axum-extra/CHANGELOG.md b/axum-extra/CHANGELOG.md index 3c7c5671..5f299345 100644 --- a/axum-extra/CHANGELOG.md +++ b/axum-extra/CHANGELOG.md @@ -9,8 +9,16 @@ and this project adheres to [Semantic Versioning]. introduced as an implicit feature through an optional dependency which was no longer being used ([#3298]) - **breaking:** `option_layer` now maps the `Response` body type to `axum::body::Body` ([#3469]) +- **breaking:** Some new features are added which need to be opted in ([#3485]). + - `Cached` extractor requires `cached` feature. + - The handler utilities require `handler` feature. + - The middleware utilities require `middleware` feature. + - `OptionalPath` extractor requires `optional-path` feature. + - The routing utilities require `routing` feature. + - `WithRejection` extractor requires `with-rejection` feature. [#3298]: https://github.com/tokio-rs/axum/pull/3298 +[#3485]: https://github.com/tokio-rs/axum/pull/3485 # 0.11.0 diff --git a/axum-extra/Cargo.toml b/axum-extra/Cargo.toml index bdb5fc6b..89ddbd88 100644 --- a/axum-extra/Cargo.toml +++ b/axum-extra/Cargo.toml @@ -40,6 +40,7 @@ allowed = [ default = ["tracing"] async-read-body = ["dep:tokio-util", "tokio-util?/io", "dep:tokio"] +cached = ["dep:axum"] file-stream = [ "dep:tokio-util", "tokio-util?/io", @@ -54,7 +55,13 @@ cookie-private = ["cookie", "cookie?/private"] cookie-signed = ["cookie", "cookie?/signed"] cookie-key-expansion = ["cookie", "cookie?/key-expansion"] erased-json = ["dep:serde_json", "dep:typed-json"] -form = ["dep:form_urlencoded", "dep:serde_html_form", "dep:serde_path_to_error"] +form = [ + "dep:axum", + "dep:form_urlencoded", + "dep:serde_html_form", + "dep:serde_path_to_error", +] +handler = ["dep:axum"] json-deserializer = ["dep:serde_json", "dep:serde_path_to_error"] json-lines = [ "dep:serde_json", @@ -64,8 +71,11 @@ json-lines = [ "tokio-stream?/io-util", "dep:tokio", ] +middleware = ["dep:axum"] multipart = ["dep:multer", "dep:fastrand"] +optional-path = ["dep:axum"] protobuf = ["dep:prost"] +routing = ["axum/original-uri"] scheme = [] query = ["dep:form_urlencoded", "dep:serde_html_form", "dep:serde_path_to_error"] tracing = ["axum-core/tracing", "axum/tracing", "dep:tracing"] @@ -76,13 +86,13 @@ typed-routing = [ "dep:serde_html_form", "dep:form_urlencoded", ] +with-rejection = ["dep:axum"] # Enabled by docs.rs because it uses all-features # Enables upstream things linked to in docs __private_docs = ["axum/json", "dep:serde"] [dependencies] -axum = { path = "../axum", version = "0.8.4", default-features = false, features = ["original-uri"] } axum-core = { path = "../axum-core", version = "0.5.2" } bytes = "1.1.0" futures-core = "0.3" @@ -99,6 +109,7 @@ tower-layer = "0.3" tower-service = "0.3" # optional dependencies +axum = { path = "../axum", version = "0.8.4", default-features = false, optional = true } axum-macros = { path = "../axum-macros", version = "0.5.0", optional = true } cookie = { package = "cookie", version = "0.18.0", features = ["percent-encode"], optional = true } fastrand = { version = "2.1.0", optional = true } diff --git a/axum-extra/src/body/async_read_body.rs b/axum-extra/src/body/async_read_body.rs index ec273b05..972965dc 100644 --- a/axum-extra/src/body/async_read_body.rs +++ b/axum-extra/src/body/async_read_body.rs @@ -1,8 +1,10 @@ -use axum::{ - body::{Body, Bytes, HttpBody}, +use axum_core::{ + body::Body, response::{IntoResponse, Response}, Error, }; +use bytes::Bytes; +use http_body::Body as HttpBody; use pin_project_lite::pin_project; use std::{ pin::Pin, diff --git a/axum-extra/src/either.rs b/axum-extra/src/either.rs index 9f426c95..5c76d13f 100755 --- a/axum-extra/src/either.rs +++ b/axum-extra/src/either.rs @@ -92,7 +92,7 @@ use std::task::{Context, Poll}; -use axum::{ +use axum_core::{ extract::FromRequestParts, response::{IntoResponse, Response}, }; diff --git a/axum-extra/src/extract/cookie/mod.rs b/axum-extra/src/extract/cookie/mod.rs index 565c89a7..372a2212 100644 --- a/axum-extra/src/extract/cookie/mod.rs +++ b/axum-extra/src/extract/cookie/mod.rs @@ -2,7 +2,7 @@ //! //! See [`CookieJar`], [`SignedCookieJar`], and [`PrivateCookieJar`] for more details. -use axum::{ +use axum_core::{ extract::FromRequestParts, response::{IntoResponse, IntoResponseParts, Response, ResponseParts}, }; diff --git a/axum-extra/src/extract/cookie/private.rs b/axum-extra/src/extract/cookie/private.rs index 2e8e504c..a5a7cd74 100644 --- a/axum-extra/src/extract/cookie/private.rs +++ b/axum-extra/src/extract/cookie/private.rs @@ -1,5 +1,5 @@ use super::{cookies_from_request, set_cookies, Cookie, Key}; -use axum::{ +use axum_core::{ extract::{FromRef, FromRequestParts}, response::{IntoResponse, IntoResponseParts, Response, ResponseParts}, }; diff --git a/axum-extra/src/extract/cookie/signed.rs b/axum-extra/src/extract/cookie/signed.rs index a258d7b9..3cfd62e2 100644 --- a/axum-extra/src/extract/cookie/signed.rs +++ b/axum-extra/src/extract/cookie/signed.rs @@ -1,5 +1,5 @@ use super::{cookies_from_request, set_cookies}; -use axum::{ +use axum_core::{ extract::{FromRef, FromRequestParts}, response::{IntoResponse, IntoResponseParts, Response, ResponseParts}, }; diff --git a/axum-extra/src/extract/host.rs b/axum-extra/src/extract/host.rs index 0f33a4ab..c4f11e72 100644 --- a/axum-extra/src/extract/host.rs +++ b/axum-extra/src/extract/host.rs @@ -1,5 +1,5 @@ use super::rejection::{FailedToResolveHost, HostRejection}; -use axum::{ +use axum_core::{ extract::{FromRequestParts, OptionalFromRequestParts}, RequestPartsExt, }; diff --git a/axum-extra/src/extract/json_deserializer.rs b/axum-extra/src/extract/json_deserializer.rs index 2d1208f9..81726960 100644 --- a/axum-extra/src/extract/json_deserializer.rs +++ b/axum-extra/src/extract/json_deserializer.rs @@ -1,7 +1,7 @@ -use axum::extract::{FromRequest, Request}; use axum_core::__composite_rejection as composite_rejection; use axum_core::__define_rejection as define_rejection; use axum_core::extract::rejection::BytesRejection; +use axum_core::extract::{FromRequest, Request}; use bytes::Bytes; use http::{header, HeaderMap}; use serde_core::Deserialize; diff --git a/axum-extra/src/extract/mod.rs b/axum-extra/src/extract/mod.rs index f14460f7..cd55ecf2 100644 --- a/axum-extra/src/extract/mod.rs +++ b/axum-extra/src/extract/mod.rs @@ -1,9 +1,15 @@ //! Additional extractors. -mod cached; mod host; -mod optional_path; pub mod rejection; + +#[cfg(feature = "optional-path")] +mod optional_path; + +#[cfg(feature = "cached")] +mod cached; + +#[cfg(feature = "with-rejection")] mod with_rejection; #[cfg(feature = "form")] @@ -25,8 +31,16 @@ pub mod multipart; mod scheme; #[allow(deprecated)] +#[cfg(feature = "optional-path")] pub use self::optional_path::OptionalPath; -pub use self::{cached::Cached, host::Host, with_rejection::WithRejection}; + +pub use self::host::Host; + +#[cfg(feature = "cached")] +pub use self::cached::Cached; + +#[cfg(feature = "with-rejection")] +pub use self::with_rejection::WithRejection; #[cfg(feature = "cookie")] pub use self::cookie::CookieJar; diff --git a/axum-extra/src/extract/multipart.rs b/axum-extra/src/extract/multipart.rs index 39d67a0c..b3d86c4c 100644 --- a/axum-extra/src/extract/multipart.rs +++ b/axum-extra/src/extract/multipart.rs @@ -2,14 +2,14 @@ //! //! See [`Multipart`] for more details. -use axum::{ - body::{Body, Bytes}, +use axum_core::{ + RequestExt, __composite_rejection as composite_rejection, + __define_rejection as define_rejection, + body::Body, extract::FromRequest, response::{IntoResponse, Response}, - RequestExt, }; -use axum_core::__composite_rejection as composite_rejection; -use axum_core::__define_rejection as define_rejection; +use bytes::Bytes; use futures_core::stream::Stream; use http::{ header::{HeaderMap, CONTENT_TYPE}, @@ -284,7 +284,7 @@ fn status_code_from_multer_error(err: &multer::Error) -> StatusCode { } if err - .downcast_ref::() + .downcast_ref::() .and_then(|err| err.source()) .and_then(|err| err.downcast_ref::()) .is_some() diff --git a/axum-extra/src/extract/query.rs b/axum-extra/src/extract/query.rs index c2caf03c..1ceb9fc9 100644 --- a/axum-extra/src/extract/query.rs +++ b/axum-extra/src/extract/query.rs @@ -1,6 +1,6 @@ -use axum::extract::FromRequestParts; use axum_core::__composite_rejection as composite_rejection; use axum_core::__define_rejection as define_rejection; +use axum_core::extract::FromRequestParts; use http::{request::Parts, Uri}; use serde_core::de::DeserializeOwned; diff --git a/axum-extra/src/extract/scheme.rs b/axum-extra/src/extract/scheme.rs index 3634bb26..dd37413e 100644 --- a/axum-extra/src/extract/scheme.rs +++ b/axum-extra/src/extract/scheme.rs @@ -1,8 +1,7 @@ //! Extractor that parses the scheme of a request. //! See [`Scheme`] for more details. -use axum::extract::FromRequestParts; -use axum_core::__define_rejection as define_rejection; +use axum_core::{__define_rejection as define_rejection, extract::FromRequestParts}; use http::{ header::{HeaderMap, FORWARDED}, request::Parts, diff --git a/axum-extra/src/json_lines.rs b/axum-extra/src/json_lines.rs index 0b52af72..20d1e449 100644 --- a/axum-extra/src/json_lines.rs +++ b/axum-extra/src/json_lines.rs @@ -1,6 +1,6 @@ //! Newline delimited JSON extractor and response. -use axum::{ +use axum_core::{ body::Body, extract::{FromRequest, Request}, response::{IntoResponse, Response}, @@ -74,7 +74,7 @@ pin_project! { }, Extractor { #[pin] - stream: BoxStream<'static, Result>, + stream: BoxStream<'static, Result>, }, } } @@ -117,9 +117,9 @@ where let deserialized_stream = lines_stream - .map_err(axum::Error::new) + .map_err(axum_core::Error::new) .and_then(|value| async move { - serde_json::from_str::(&value).map_err(axum::Error::new) + serde_json::from_str::(&value).map_err(axum_core::Error::new) }); Ok(Self { @@ -132,7 +132,7 @@ where } impl Stream for JsonLines { - type Item = Result; + type Item = Result; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.project().inner.project() { diff --git a/axum-extra/src/lib.rs b/axum-extra/src/lib.rs index 67d50137..7306eb04 100644 --- a/axum-extra/src/lib.rs +++ b/axum-extra/src/lib.rs @@ -11,6 +11,7 @@ //! ---|---|--- //! `async-read-body` | Enables the [`AsyncReadBody`](crate::body::AsyncReadBody) body | No //! `attachment` | Enables the [`Attachment`](crate::response::Attachment) response | No +//! `cached` | Enables the [`Cached`](crate::extract::Cached) extractor | No //! `cookie` | Enables the [`CookieJar`](crate::extract::CookieJar) extractor | No //! `cookie-private` | Enables the [`PrivateCookieJar`](crate::extract::PrivateCookieJar) extractor | No //! `cookie-signed` | Enables the [`SignedCookieJar`](crate::extract::SignedCookieJar) extractor | No @@ -18,15 +19,20 @@ //! `erased-json` | Enables the [`ErasedJson`](crate::response::ErasedJson) response | No //! `error-response` | Enables the [`InternalServerError`](crate::response::InternalServerError) response | No //! `form` | Enables the [`Form`](crate::extract::Form) extractor | No +//! `handler` | Enables the [handler] utilities | No //! `json-deserializer` | Enables the [`JsonDeserializer`](crate::extract::JsonDeserializer) extractor | No //! `json-lines` | Enables the [`JsonLines`](crate::extract::JsonLines) extractor and response | No +//! `middleware` | Enables the [middleware] utilities | No //! `multipart` | Enables the [`Multipart`](crate::extract::Multipart) extractor | No +//! `optional-path` | Enables the [`OptionalPath`](crate::extract::OptionalPath) extractor | No //! `protobuf` | Enables the [`Protobuf`](crate::protobuf::Protobuf) extractor and response | No //! `query` | Enables the [`Query`](crate::extract::Query) extractor | No +//! `routing` | Enables the [routing] utilities | No //! `tracing` | Log rejections from built-in extractors | Yes //! `typed-routing` | Enables the [`TypedPath`](crate::routing::TypedPath) routing utilities | No //! `typed-header` | Enables the [`TypedHeader`] extractor and response | No //! `file-stream` | Enables the [`FileStream`](crate::response::FileStream) response | No +//! `with-rejection` | Enables the [`WithRejection`](crate::extract::WithRejection) extractor | No //! //! [`axum`]: https://crates.io/crates/axum @@ -40,11 +46,17 @@ extern crate self as axum_extra; pub mod body; pub mod either; pub mod extract; -pub mod handler; -pub mod middleware; pub mod response; + +#[cfg(feature = "routing")] pub mod routing; +#[cfg(feature = "middleware")] +pub mod middleware; + +#[cfg(feature = "handler")] +pub mod handler; + #[cfg(feature = "json-lines")] pub mod json_lines; diff --git a/axum-extra/src/protobuf.rs b/axum-extra/src/protobuf.rs index 9ec87898..2f179a11 100644 --- a/axum-extra/src/protobuf.rs +++ b/axum-extra/src/protobuf.rs @@ -1,12 +1,12 @@ //! Protocol Buffer extractor and response. -use axum::{ +use axum_core::__composite_rejection as composite_rejection; +use axum_core::__define_rejection as define_rejection; +use axum_core::{ extract::{rejection::BytesRejection, FromRequest, Request}, response::{IntoResponse, Response}, RequestExt, }; -use axum_core::__composite_rejection as composite_rejection; -use axum_core::__define_rejection as define_rejection; use bytes::BytesMut; use http::StatusCode; use http_body_util::BodyExt; diff --git a/axum-extra/src/response/attachment.rs b/axum-extra/src/response/attachment.rs index 2063d30f..b2af0aed 100644 --- a/axum-extra/src/response/attachment.rs +++ b/axum-extra/src/response/attachment.rs @@ -1,4 +1,4 @@ -use axum::response::IntoResponse; +use axum_core::response::IntoResponse; use http::{header, HeaderMap, HeaderValue}; use tracing::error; @@ -79,7 +79,7 @@ impl IntoResponse for Attachment where T: IntoResponse, { - fn into_response(self) -> axum::response::Response { + fn into_response(self) -> axum_core::response::Response { let mut headers = HeaderMap::new(); if let Some(content_type) = self.content_type { diff --git a/axum-extra/src/response/erased_json.rs b/axum-extra/src/response/erased_json.rs index de0fc221..76c7390e 100644 --- a/axum-extra/src/response/erased_json.rs +++ b/axum-extra/src/response/erased_json.rs @@ -1,10 +1,8 @@ use std::sync::Arc; -use axum::{ - http::{header, HeaderValue, StatusCode}, - response::{IntoResponse, Response}, -}; +use axum_core::response::{IntoResponse, Response}; use bytes::{BufMut, Bytes, BytesMut}; +use http::{header, HeaderValue, StatusCode}; use serde_core::Serialize; /// A response type that holds a JSON in serialized form. diff --git a/axum-extra/src/response/file_stream.rs b/axum-extra/src/response/file_stream.rs index 790f103f..9d1f11d5 100644 --- a/axum-extra/src/response/file_stream.rs +++ b/axum-extra/src/response/file_stream.rs @@ -1,4 +1,4 @@ -use axum::{ +use axum_core::{ body, response::{IntoResponse, Response}, BoxError, diff --git a/axum-extra/src/response/mod.rs b/axum-extra/src/response/mod.rs index 40a549f9..5460c694 100644 --- a/axum-extra/src/response/mod.rs +++ b/axum-extra/src/response/mod.rs @@ -60,11 +60,11 @@ macro_rules! mime_response { #[must_use] pub struct $ident(pub T); - impl axum::response::IntoResponse for $ident + impl axum_core::response::IntoResponse for $ident where - T: axum::response::IntoResponse, + T: axum_core::response::IntoResponse, { - fn into_response(self) -> axum::response::Response { + fn into_response(self) -> axum_core::response::Response { ( [( http::header::CONTENT_TYPE, diff --git a/axum-extra/src/response/multiple.rs b/axum-extra/src/response/multiple.rs index 310210a1..a9d674dc 100644 --- a/axum-extra/src/response/multiple.rs +++ b/axum-extra/src/response/multiple.rs @@ -1,6 +1,6 @@ //! Generate forms to use in responses. -use axum::response::{IntoResponse, Response}; +use axum_core::response::{IntoResponse, Response}; use fastrand; use http::{header, HeaderMap, StatusCode}; use mime::Mime; diff --git a/axum-extra/src/typed_header.rs b/axum-extra/src/typed_header.rs index 41cf9181..70f9ff9c 100644 --- a/axum-extra/src/typed_header.rs +++ b/axum-extra/src/typed_header.rs @@ -1,6 +1,6 @@ //! Extractor and response for typed headers. -use axum::{ +use axum_core::{ extract::{FromRequestParts, OptionalFromRequestParts}, response::{IntoResponse, IntoResponseParts, Response, ResponseParts}, }; diff --git a/axum-macros/Cargo.toml b/axum-macros/Cargo.toml index 049de497..223cc783 100644 --- a/axum-macros/Cargo.toml +++ b/axum-macros/Cargo.toml @@ -36,7 +36,7 @@ syn = { version = "2.0", features = [ [dev-dependencies] axum = { path = "../axum", features = ["macros"] } -axum-extra = { path = "../axum-extra", features = ["typed-routing", "cookie-private", "typed-header"] } +axum-extra = { path = "../axum-extra", features = ["typed-routing", "cookie-private", "typed-header", "routing"] } rustversion = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/examples/customize-extractor-error/Cargo.toml b/examples/customize-extractor-error/Cargo.toml index 8e86df21..5f406232 100644 --- a/examples/customize-extractor-error/Cargo.toml +++ b/examples/customize-extractor-error/Cargo.toml @@ -6,7 +6,7 @@ publish = false [dependencies] axum = { path = "../../axum", features = ["macros"] } -axum-extra = { path = "../../axum-extra" } +axum-extra = { path = "../../axum-extra", features = ["with-rejection"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0"