Skip to content

Commit

Permalink
Fix cargo hack warnings (#3114)
Browse files Browse the repository at this point in the history
  • Loading branch information
Turbo87 authored Dec 27, 2024
1 parent ed4d560 commit 32a948e
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 91 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ jobs:

cargo-hack:
runs-on: ubuntu-24.04
env:
# Fail the build if there are any warnings
RUSTFLAGS: "-D warnings"
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
Expand Down
4 changes: 3 additions & 1 deletion axum/src/extract/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ pub mod rejection;
pub mod ws;

pub(crate) mod nested_path;
#[cfg(feature = "original-uri")]
mod original_uri;
mod raw_form;
mod raw_query;
mod request_parts;
Expand Down Expand Up @@ -72,7 +74,7 @@ pub use self::query::Query;

#[cfg(feature = "original-uri")]
#[doc(inline)]
pub use self::request_parts::OriginalUri;
pub use self::original_uri::OriginalUri;

#[cfg(feature = "ws")]
#[doc(inline)]
Expand Down
85 changes: 85 additions & 0 deletions axum/src/extract/original_uri.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use super::{Extension, FromRequestParts};
use http::{request::Parts, Uri};
use std::convert::Infallible;

/// Extractor that gets the original request URI regardless of nesting.
///
/// This is necessary since [`Uri`](http::Uri), when used as an extractor, will
/// have the prefix stripped if used in a nested service.
///
/// # Example
///
/// ```
/// use axum::{
/// routing::get,
/// Router,
/// extract::OriginalUri,
/// http::Uri
/// };
///
/// let api_routes = Router::new()
/// .route(
/// "/users",
/// get(|uri: Uri, OriginalUri(original_uri): OriginalUri| async {
/// // `uri` is `/users`
/// // `original_uri` is `/api/users`
/// }),
/// );
///
/// let app = Router::new().nest("/api", api_routes);
/// # let _: Router = app;
/// ```
///
/// # Extracting via request extensions
///
/// `OriginalUri` can also be accessed from middleware via request extensions.
/// This is useful for example with [`Trace`](tower_http::trace::Trace) to
/// create a span that contains the full path, if your service might be nested:
///
/// ```
/// use axum::{
/// Router,
/// extract::OriginalUri,
/// http::Request,
/// routing::get,
/// };
/// use tower_http::trace::TraceLayer;
///
/// let api_routes = Router::new()
/// .route("/users/{id}", get(|| async { /* ... */ }))
/// .layer(
/// TraceLayer::new_for_http().make_span_with(|req: &Request<_>| {
/// let path = if let Some(path) = req.extensions().get::<OriginalUri>() {
/// // This will include `/api`
/// path.0.path().to_owned()
/// } else {
/// // The `OriginalUri` extension will always be present if using
/// // `Router` unless another extractor or middleware has removed it
/// req.uri().path().to_owned()
/// };
/// tracing::info_span!("http-request", %path)
/// }),
/// );
///
/// let app = Router::new().nest("/api", api_routes);
/// # let _: Router = app;
/// ```
#[derive(Debug, Clone)]
pub struct OriginalUri(pub Uri);

impl<S> FromRequestParts<S> for OriginalUri
where
S: Send + Sync,
{
type Rejection = Infallible;

async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
let uri = Extension::<Self>::from_request_parts(parts, state)
.await
.unwrap_or_else(|_| Extension(OriginalUri(parts.uri.clone())))
.0;
Ok(uri)
}
}

axum_core::__impl_deref!(OriginalUri: Uri);
92 changes: 3 additions & 89 deletions axum/src/extract/request_parts.rs
Original file line number Diff line number Diff line change
@@ -1,92 +1,6 @@
use super::{Extension, FromRequestParts};
use http::{request::Parts, Uri};
use std::convert::Infallible;

/// Extractor that gets the original request URI regardless of nesting.
///
/// This is necessary since [`Uri`](http::Uri), when used as an extractor, will
/// have the prefix stripped if used in a nested service.
///
/// # Example
///
/// ```
/// use axum::{
/// routing::get,
/// Router,
/// extract::OriginalUri,
/// http::Uri
/// };
///
/// let api_routes = Router::new()
/// .route(
/// "/users",
/// get(|uri: Uri, OriginalUri(original_uri): OriginalUri| async {
/// // `uri` is `/users`
/// // `original_uri` is `/api/users`
/// }),
/// );
///
/// let app = Router::new().nest("/api", api_routes);
/// # let _: Router = app;
/// ```
///
/// # Extracting via request extensions
///
/// `OriginalUri` can also be accessed from middleware via request extensions.
/// This is useful for example with [`Trace`](tower_http::trace::Trace) to
/// create a span that contains the full path, if your service might be nested:
///
/// ```
/// use axum::{
/// Router,
/// extract::OriginalUri,
/// http::Request,
/// routing::get,
/// };
/// use tower_http::trace::TraceLayer;
///
/// let api_routes = Router::new()
/// .route("/users/{id}", get(|| async { /* ... */ }))
/// .layer(
/// TraceLayer::new_for_http().make_span_with(|req: &Request<_>| {
/// let path = if let Some(path) = req.extensions().get::<OriginalUri>() {
/// // This will include `/api`
/// path.0.path().to_owned()
/// } else {
/// // The `OriginalUri` extension will always be present if using
/// // `Router` unless another extractor or middleware has removed it
/// req.uri().path().to_owned()
/// };
/// tracing::info_span!("http-request", %path)
/// }),
/// );
///
/// let app = Router::new().nest("/api", api_routes);
/// # let _: Router = app;
/// ```
#[cfg(feature = "original-uri")]
#[derive(Debug, Clone)]
pub struct OriginalUri(pub Uri);

#[cfg(feature = "original-uri")]
impl<S> FromRequestParts<S> for OriginalUri
where
S: Send + Sync,
{
type Rejection = Infallible;

async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
let uri = Extension::<Self>::from_request_parts(parts, state)
.await
.unwrap_or_else(|_| Extension(OriginalUri(parts.uri.clone())))
.0;
Ok(uri)
}
}

#[cfg(feature = "original-uri")]
axum_core::__impl_deref!(OriginalUri: Uri);

/// This module contains the tests for the `impl<S> FromRequestParts<S> for Parts`
/// implementation in the `axum-core` crate. The tests cannot be moved there
/// because we don't have access to the `TestClient` and `Router` types there.
#[cfg(test)]
mod tests {
use crate::{extract::Extension, routing::get, test_helpers::*, Router};
Expand Down
4 changes: 4 additions & 0 deletions axum/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,25 +68,29 @@ macro_rules! all_the_tuples {
}

#[cfg(feature = "tracing")]
#[allow(unused_macros)]
macro_rules! trace {
($($tt:tt)*) => {
tracing::trace!($($tt)*)
}
}

#[cfg(feature = "tracing")]
#[allow(unused_macros)]
macro_rules! error {
($($tt:tt)*) => {
tracing::error!($($tt)*)
};
}

#[cfg(not(feature = "tracing"))]
#[allow(unused_macros)]
macro_rules! trace {
($($tt:tt)*) => {};
}

#[cfg(not(feature = "tracing"))]
#[allow(unused_macros)]
macro_rules! error {
($($tt:tt)*) => {};
}
1 change: 1 addition & 0 deletions axum/src/routing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ impl<S> fmt::Debug for Router<S> {
}

pub(crate) const NEST_TAIL_PARAM: &str = "__private__axum_nest_tail_param";
#[cfg(feature = "matched-path")]
pub(crate) const NEST_TAIL_PARAM_CAPTURE: &str = "/{*__private__axum_nest_tail_param}";
pub(crate) const FALLBACK_PARAM: &str = "__private__axum_fallback";
pub(crate) const FALLBACK_PARAM_PATH: &str = "/{*__private__axum_fallback}";
Expand Down
2 changes: 1 addition & 1 deletion axum/src/routing/path_router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ where

pub(super) fn call_with_state(
&self,
mut req: Request,
#[cfg_attr(not(feature = "original-uri"), allow(unused_mut))] mut req: Request,
state: S,
) -> Result<RouteFuture<Infallible>, (Request, S)> {
#[cfg(feature = "original-uri")]
Expand Down

0 comments on commit 32a948e

Please sign in to comment.