Repository: tokio-rs/axum
File: axum/src/middleware/map_request.rs (Rust)

Code before:
/// };
///
/// #[derive(Clone)]
/// struct AppState { /* ... */ }
///
/// async fn my_middleware<B>(
///     State(state): State<AppState>,
///     // you can add more extractors here...
///     request: Request<B>,
/// ) -> Request<B> {
///     // do something with `request`...
///     request
/// }
///
/// let state = AppState { /* ... */ };
///
/// let app = Router::with_state(state.clone())
///     .route("/", get(|| async { /* ... */ }))
///     .route_layer(map_request_with_state(state, my_middleware));
/// # let app: Router<_> = app;
/// ```
pub fn map_request_with_state<F, S, T>(state: S, f: F) -> MapRequestLayer<F, S, T> {
    map_request_with_state_arc(Arc::new(state), f)
}

/// Create a middleware from an async function, that transforms a request, with the given [`Arc`]'ed
/// state.
///
/// See [`map_request_with_state`] for an example.
///
/// See [`State`](crate::extract::State) for more details about accessing state.
pub fn map_request_with_state_arc<F, S, T>(state: Arc<S>, f: F) -> MapRequestLayer<F, S, T> {
    MapRequestLayer {
        f,
        state,
        _extractor: PhantomData,
    }
}

/// A [`tower::Layer`] from an async function that transforms a request.
///
/// Created with [`map_request`]. See that function for more details.
pub struct MapRequestLayer<F, S, T> {
    f: F,
    state: Arc<S>,
    _extractor: PhantomData<fn() -> T>,
}

impl<F, S, T> Clone for MapRequestLayer<F, S, T>
where
    F: Clone,

Review comment (suggestion):
```suggestion
/// Create a middleware from an async function that transforms a request, with the given [`Arc`]'ed
```

Code after:
/// };
///
/// #[derive(Clone)]
/// struct AppState { /* ... */ }
///
/// async fn my_middleware<B>(
///     State(state): State<AppState>,
///     // you can add more extractors here but the last
///     // extractor must implement `FromRequest` which
///     // `Request` does
///     request: Request<B>,
/// ) -> Request<B> {
///     // do something with `state` and `request`...
///     request
/// }
///
/// let state = AppState { /* ... */ };
///
/// let app = Router::with_state(state.clone())
///     .route("/", get(|| async { /* ... */ }))
///     .route_layer(map_request_with_state(state, my_middleware));
/// # let app: Router<_> = app;
/// ```
pub fn map_request_with_state<F, S, T>(state: S, f: F) -> MapRequestLayer<F, S, T> {
    map_request_with_state_arc(Arc::new(state), f)
}

/// Create a middleware from an async function that transforms a request, with the given [`Arc`]'ed
/// state.
///
/// See [`map_request_with_state`] for an example.
///
/// See [`State`](crate::extract::State) for more details about accessing state.
pub fn map_request_with_state_arc<F, S, T>(state: Arc<S>, f: F) -> MapRequestLayer<F, S, T> {
    MapRequestLayer {
        f,
        state,
        _extractor: PhantomData,
    }
}

/// A [`tower::Layer`] from an async function that transforms a request.
///
/// Created with [`map_request`]. See that function for more details.
pub struct MapRequestLayer<F, S, T> {
    f: F,
    state: Arc<S>,
    _extractor: PhantomData<fn() -> T>,
}

impl<F, S, T> Clone for MapRequestLayer<F, S, T>