mirror of
https://github.com/tokio-rs/axum.git
synced 2025-01-21 07:50:49 +01:00
Clarify Clone
requirements for using State
(#1388)
This commit is contained in:
parent
c81549d95b
commit
21876fcc64
1 changed files with 50 additions and 1 deletions
|
@ -22,7 +22,9 @@ use std::{
|
||||||
/// //
|
/// //
|
||||||
/// // here you can put configuration, database connection pools, or whatever
|
/// // here you can put configuration, database connection pools, or whatever
|
||||||
/// // state you need
|
/// // state you need
|
||||||
/// // Note: the application state *must* derive `Clone` (or be wrapped in e.g. `Arc`)
|
/// //
|
||||||
|
/// // see "When states need to implement `Clone`" for more details on why we need
|
||||||
|
/// // `#[derive(Clone)]` here.
|
||||||
/// #[derive(Clone)]
|
/// #[derive(Clone)]
|
||||||
/// struct AppState {}
|
/// struct AppState {}
|
||||||
///
|
///
|
||||||
|
@ -173,6 +175,53 @@ use std::{
|
||||||
/// // ...
|
/// // ...
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// # When states need to implement `Clone`
|
||||||
|
///
|
||||||
|
/// Your top level state type must implement `Clone` to be extractable with `State`:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use axum::extract::State;
|
||||||
|
///
|
||||||
|
/// // no substates, so to extract to `State<AppState>` we must implement `Clone` for `AppState`
|
||||||
|
/// #[derive(Clone)]
|
||||||
|
/// struct AppState {}
|
||||||
|
///
|
||||||
|
/// async fn handler(State(state): State<AppState>) {
|
||||||
|
/// // ...
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// This works because of [`impl<S> FromRef<S> for S where S: Clone`][`FromRef`].
|
||||||
|
///
|
||||||
|
/// This is also true if you're extracting substates, unless you _never_ extract the top level
|
||||||
|
/// state itself:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use axum::extract::{State, FromRef};
|
||||||
|
///
|
||||||
|
/// // we never extract `State<AppState>`, just `State<InnerState>`. So `AppState` doesn't need to
|
||||||
|
/// // implement `Clone`
|
||||||
|
/// struct AppState {
|
||||||
|
/// inner: InnerState,
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// #[derive(Clone)]
|
||||||
|
/// struct InnerState {}
|
||||||
|
///
|
||||||
|
/// impl FromRef<AppState> for InnerState {
|
||||||
|
/// fn from_ref(app_state: &AppState) -> InnerState {
|
||||||
|
/// app_state.inner.clone()
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// async fn api_users(State(inner): State<InnerState>) {
|
||||||
|
/// // ...
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// In general however we recommend you implement `Clone` to all your state types to avoid
|
||||||
|
/// potential type errors.
|
||||||
#[derive(Debug, Default, Clone, Copy)]
|
#[derive(Debug, Default, Clone, Copy)]
|
||||||
pub struct State<S>(pub S);
|
pub struct State<S>(pub S);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue