Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move TypedHeader to axum-extra #1850

Merged
merged 16 commits into from
Apr 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
# same as `axum-macros/rust-toolchain`
toolchain: nightly-2022-11-18
toolchain: nightly-2023-04-06
override: true
profile: minimal
- uses: Swatinem/rust-cache@v1
Expand Down
3 changes: 2 additions & 1 deletion axum-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ tower-http = { version = "0.4", optional = true, features = ["limit"] }
rustversion = "1.0.9"

[dev-dependencies]
axum = { path = "../axum", version = "0.6.0", features = ["headers"] }
axum = { path = "../axum", version = "0.6.0" }
axum-extra = { path = "../axum-extra", features = ["typed-header"] }
futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
hyper = "0.14.24"
tokio = { version = "1.25.0", features = ["macros"] }
Expand Down
22 changes: 12 additions & 10 deletions axum-core/src/ext_traits/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,15 +139,19 @@ pub trait RequestExt: sealed::Sealed + Sized {
/// ```
/// use axum::{
/// async_trait,
/// extract::{Request, FromRequest},
/// headers::{authorization::Bearer, Authorization},
/// extract::{Path, Request, FromRequest},
/// response::{IntoResponse, Response},
/// body::Body,
/// Json, RequestExt, TypedHeader,
/// Json, RequestExt,
/// };
/// use axum_extra::{
/// TypedHeader,
/// headers::{authorization::Bearer, Authorization},
/// };
/// use std::collections::HashMap;
///
/// struct MyExtractor<T> {
/// bearer_token: String,
/// path_params: HashMap<String, String>,
/// payload: T,
/// }
///
Expand All @@ -161,20 +165,18 @@ pub trait RequestExt: sealed::Sealed + Sized {
/// type Rejection = Response;
///
/// async fn from_request(mut req: Request, _state: &S) -> Result<Self, Self::Rejection> {
/// let TypedHeader(auth_header) = req
/// .extract_parts::<TypedHeader<Authorization<Bearer>>>()
/// let path_params = req
/// .extract_parts::<Path<_>>()
/// .await
/// .map(|Path(path_params)| path_params)
/// .map_err(|err| err.into_response())?;
///
/// let Json(payload) = req
/// .extract::<Json<T>, _>()
/// .await
/// .map_err(|err| err.into_response())?;
///
/// Ok(Self {
/// bearer_token: auth_header.token().to_owned(),
/// payload,
/// })
/// Ok(Self { path_params, payload })
/// }
/// }
/// ```
Expand Down
13 changes: 6 additions & 7 deletions axum-core/src/ext_traits/request_parts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,16 @@ pub trait RequestPartsExt: sealed::Sealed + Sized {
///
/// ```
/// use axum::{
/// extract::{Query, TypedHeader, FromRequestParts},
/// extract::{Query, Path, FromRequestParts},
/// response::{Response, IntoResponse},
/// headers::UserAgent,
/// http::request::Parts,
/// RequestPartsExt,
/// async_trait,
/// };
/// use std::collections::HashMap;
///
/// struct MyExtractor {
/// user_agent: String,
/// path_params: HashMap<String, String>,
/// query_params: HashMap<String, String>,
/// }
///
Expand All @@ -39,10 +38,10 @@ pub trait RequestPartsExt: sealed::Sealed + Sized {
/// type Rejection = Response;
///
/// async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
/// let user_agent = parts
/// .extract::<TypedHeader<UserAgent>>()
/// let path_params = parts
/// .extract::<Path<HashMap<String, String>>>()
/// .await
/// .map(|user_agent| user_agent.as_str().to_owned())
/// .map(|Path(path_params)| path_params)
/// .map_err(|err| err.into_response())?;
///
/// let query_params = parts
Expand All @@ -51,7 +50,7 @@ pub trait RequestPartsExt: sealed::Sealed + Sized {
/// .map(|Query(params)| params)
/// .map_err(|err| err.into_response())?;
///
/// Ok(MyExtractor { user_agent, query_params })
/// Ok(MyExtractor { path_params, query_params })
/// }
/// }
/// ```
Expand Down
4 changes: 3 additions & 1 deletion axum-extra/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning].

# Unreleased

- None.
- **added:** Added `TypedHeader` which used to be in `axum` ([#1850])

[#1850]: https://github.com/tokio-rs/axum/pull/1850

# 0.7.2 (22. March, 2023)

Expand Down
10 changes: 7 additions & 3 deletions axum-extra/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ json-lines = [
multipart = ["dep:multer"]
protobuf = ["dep:prost"]
query = ["dep:serde", "dep:serde_html_form"]
typed-header = ["dep:headers"]
typed-routing = ["dep:axum-macros", "dep:serde", "dep:percent-encoding", "dep:serde_html_form", "dep:form_urlencoded"]

[dependencies]
Expand All @@ -52,6 +53,7 @@ tower-service = "0.3"
axum-macros = { path = "../axum-macros", version = "0.3.7", optional = true }
cookie = { package = "cookie", version = "0.17", features = ["percent-encode"], optional = true }
form_urlencoded = { version = "1.1.0", optional = true }
headers = { version = "0.3.8", optional = true }
multer = { version = "2.0.0", optional = true }
percent-encoding = { version = "2.1", optional = true }
prost = { version = "0.11", optional = true }
Expand All @@ -62,7 +64,8 @@ tokio-stream = { version = "0.1.9", optional = true }
tokio-util = { version = "0.7", optional = true }

[dev-dependencies]
axum = { path = "../axum", version = "0.6.0", features = ["headers"] }
axum = { path = "../axum", version = "0.6.0" }
futures = "0.3"
http-body = "0.4.4"
hyper = "0.14"
reqwest = { version = "0.11", default-features = false, features = ["json", "stream", "multipart"] }
Expand All @@ -80,14 +83,15 @@ rustdoc-args = ["--cfg", "docsrs"]
allowed = [
"axum",
"axum_core",
"axum_macros",
"bytes",
"cookie",
"futures_core",
"futures_util",
"headers",
"headers_core",
davidpdrsn marked this conversation as resolved.
Show resolved Hide resolved
"http",
"http_body",
"hyper",
"percent_encoding",
"prost",
"serde",
"tokio",
Expand Down
8 changes: 5 additions & 3 deletions axum-extra/src/extract/cookie/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@ pub use cookie::Key;
/// use axum::{
/// Router,
/// routing::{post, get},
/// extract::TypedHeader,
/// response::{IntoResponse, Redirect},
/// headers::authorization::{Authorization, Bearer},
/// http::StatusCode,
/// };
/// use axum_extra::extract::cookie::{CookieJar, Cookie};
/// use axum_extra::{
/// TypedHeader,
/// headers::authorization::{Authorization, Bearer},
/// extract::cookie::{CookieJar, Cookie},
/// };
///
/// async fn create_session(
/// TypedHeader(auth): TypedHeader<Authorization<Bearer>>,
Expand Down
9 changes: 6 additions & 3 deletions axum-extra/src/extract/cookie/private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@ use std::{convert::Infallible, fmt, marker::PhantomData};
/// use axum::{
/// Router,
/// routing::{post, get},
/// extract::{TypedHeader, FromRef},
/// extract::FromRef,
/// response::{IntoResponse, Redirect},
/// headers::authorization::{Authorization, Bearer},
/// http::StatusCode,
/// };
/// use axum_extra::extract::cookie::{PrivateCookieJar, Cookie, Key};
/// use axum_extra::{
/// TypedHeader,
/// headers::authorization::{Authorization, Bearer},
/// extract::cookie::{PrivateCookieJar, Cookie, Key},
/// };
///
/// async fn set_secret(
/// jar: PrivateCookieJar,
Expand Down
9 changes: 6 additions & 3 deletions axum-extra/src/extract/cookie/signed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,15 @@ use std::{convert::Infallible, fmt, marker::PhantomData};
/// use axum::{
/// Router,
/// routing::{post, get},
/// extract::{TypedHeader, FromRef},
/// extract::FromRef,
/// response::{IntoResponse, Redirect},
/// headers::authorization::{Authorization, Bearer},
/// http::StatusCode,
/// };
/// use axum_extra::extract::cookie::{SignedCookieJar, Cookie, Key};
/// use axum_extra::{
/// TypedHeader,
/// headers::authorization::{Authorization, Bearer},
/// extract::cookie::{SignedCookieJar, Cookie, Key},
/// };
///
/// async fn create_session(
/// TypedHeader(auth): TypedHeader<Authorization<Bearer>>,
Expand Down
4 changes: 4 additions & 0 deletions axum-extra/src/extract/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,8 @@ pub use self::multipart::Multipart;
#[doc(no_inline)]
pub use crate::json_lines::JsonLines;

#[cfg(feature = "typed-header")]
#[doc(no_inline)]
pub use crate::typed_header::TypedHeader;

pub use self::with_rejection::WithRejection;
12 changes: 12 additions & 0 deletions axum-extra/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
//! `protobuf` | Enables the `Protobuf` extractor and response | No
//! `query` | Enables the `Query` extractor | No
//! `typed-routing` | Enables the `TypedPath` routing utilities | No
//! `typed-header` | Enables the `TypedHeader` extractor and response | No
//!
//! [`axum`]: https://crates.io/crates/axum

Expand Down Expand Up @@ -79,6 +80,17 @@ pub mod routing;
#[cfg(feature = "json-lines")]
pub mod json_lines;

#[cfg(feature = "typed-header")]
pub mod typed_header;

#[cfg(feature = "typed-header")]
#[doc(no_inline)]
pub use headers;

#[cfg(feature = "typed-header")]
#[doc(inline)]
pub use typed_header::TypedHeader;

#[cfg(feature = "protobuf")]
pub mod protobuf;

Expand Down
4 changes: 4 additions & 0 deletions axum-extra/src/response/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ pub use erased_json::ErasedJson;
#[cfg(feature = "json-lines")]
#[doc(no_inline)]
pub use crate::json_lines::JsonLines;

#[cfg(feature = "typed-header")]
#[doc(no_inline)]
pub use crate::typed_header::TypedHeader;
39 changes: 22 additions & 17 deletions axum/src/typed_header.rs → axum-extra/src/typed_header.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use crate::extract::FromRequestParts;
use async_trait::async_trait;
use axum_core::response::{IntoResponse, IntoResponseParts, Response, ResponseParts};
use headers::HeaderMapExt;
//! Extractor and response for typed headers.

use axum::{
async_trait,
extract::FromRequestParts,
response::{IntoResponse, IntoResponseParts, Response, ResponseParts},
};
use headers::{Header, HeaderMapExt};
use http::request::Parts;
use std::{convert::Infallible, ops::Deref};

Expand All @@ -14,11 +18,11 @@ use std::{convert::Infallible, ops::Deref};
///
/// ```rust,no_run
/// use axum::{
/// TypedHeader,
/// headers::UserAgent,
/// routing::get,
/// Router,
/// };
/// use headers::UserAgent;
/// use axum_extra::TypedHeader;
///
/// async fn users_teams_show(
/// TypedHeader(user_agent): TypedHeader<UserAgent>,
Expand All @@ -34,10 +38,10 @@ use std::{convert::Infallible, ops::Deref};
///
/// ```rust
/// use axum::{
/// TypedHeader,
/// response::IntoResponse,
/// headers::ContentType,
/// };
/// use headers::ContentType;
/// use axum_extra::TypedHeader;
///
/// async fn handler() -> (TypedHeader<ContentType>, &'static str) {
/// (
Expand All @@ -46,15 +50,15 @@ use std::{convert::Infallible, ops::Deref};
/// )
/// }
/// ```
#[cfg(feature = "headers")]
#[cfg(feature = "typed-header")]
#[derive(Debug, Clone, Copy)]
#[must_use]
pub struct TypedHeader<T>(pub T);

#[async_trait]
impl<T, S> FromRequestParts<S> for TypedHeader<T>
where
T: headers::Header,
T: Header,
S: Send + Sync,
{
type Rejection = TypedHeaderRejection;
Expand Down Expand Up @@ -86,7 +90,7 @@ impl<T> Deref for TypedHeader<T> {

impl<T> IntoResponseParts for TypedHeader<T>
where
T: headers::Header,
T: Header,
{
type Error = Infallible;

Expand All @@ -98,7 +102,7 @@ where

impl<T> IntoResponse for TypedHeader<T>
where
T: headers::Header,
T: Header,
{
fn into_response(self) -> Response {
let mut res = ().into_response();
Expand All @@ -107,8 +111,8 @@ where
}
}

/// Rejection used for [`TypedHeader`](super::TypedHeader).
#[cfg(feature = "headers")]
/// Rejection used for [`TypedHeader`](TypedHeader).
#[cfg(feature = "typed-header")]
#[derive(Debug)]
pub struct TypedHeaderRejection {
name: &'static http::header::HeaderName,
Expand All @@ -128,7 +132,7 @@ impl TypedHeaderRejection {
}

/// Additional information regarding a [`TypedHeaderRejection`]
#[cfg(feature = "headers")]
#[cfg(feature = "typed-header")]
#[derive(Debug)]
#[non_exhaustive]
pub enum TypedHeaderRejectionReason {
Expand Down Expand Up @@ -169,9 +173,10 @@ impl std::error::Error for TypedHeaderRejection {
#[cfg(test)]
mod tests {
use super::*;
use crate::{response::IntoResponse, routing::get, test_helpers::*, Router};
use crate::test_helpers::*;
use axum::{response::IntoResponse, routing::get, Router};

#[crate::test]
#[tokio::test]
async fn typed_header() {
async fn handle(
TypedHeader(user_agent): TypedHeader<headers::UserAgent>,
Expand Down
4 changes: 2 additions & 2 deletions axum-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ syn = { version = "2.0", features = [
] }

[dev-dependencies]
axum = { path = "../axum", version = "0.6.0", features = ["headers", "macros"] }
axum-extra = { path = "../axum-extra", version = "0.7.0", features = ["typed-routing", "cookie-private"] }
axum = { path = "../axum", version = "0.6.0", features = ["macros"] }
axum-extra = { path = "../axum-extra", version = "0.7.0", features = ["typed-routing", "cookie-private", "typed-header"] }
rustversion = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Expand Down
2 changes: 1 addition & 1 deletion axum-macros/rust-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1 @@
nightly-2022-11-18
nightly-2023-04-06
Loading