Repository: tokio-rs/axum
File: axum/src/extract/state.rs (Rust)

Code before:
///
/// In general however we recommend you implement `Clone` for all your state types to avoid
/// potential type errors.
///
/// # Shared mutable state
///
/// [As state is global within a `Router`][global] you can't directly get a mutable reference to
/// the state.
///
/// The most basic solution is to use an `Arc<Mutex<_>>`. Which kind of mutex you need depends on
/// your use case. See [the tokio docs] for more details.
///
/// Note that holding a locked `std::sync::Mutex` across `.await` points will result in `!Send`
/// futures which are incompatible with axum. If you need to hold a mutex across `.await` points
/// consider using a `tokio::sync::Mutex` instead.
///
/// ## Example
///
/// ```
/// use axum::{Router, routing::get, extract::State};
/// use std::sync::{Arc, Mutex};
///
/// #[derive(Clone)]
/// struct AppState {
///     data: Arc<Mutex<String>>,
/// }
///
/// async fn handler(State(state): State<AppState>) {
///     let mut data = state.data.lock().expect("mutex was poisoned");
///     *data = "updated foo".to_owned();
///
///     // ...
/// }
///
/// let state = AppState {
///     data: Arc::new(Mutex::new("foo".to_owned())),
/// };
///
/// let app = Router::new()
///     .route("/", get(handler))
///     .with_state(state);
/// # let _: Router = app;
/// ```
///
/// [global]: crate::Router::with_state
/// [the tokio docs]: https://docs.rs/tokio/1.25.0/tokio/sync/struct.Mutex.html#which-kind-of-mutex-should-you-use
#[derive(Debug, Default, Clone, Copy)]
pub struct State<S>(pub S);

#[async_trait]
impl<OuterState, InnerState> FromRequestParts<OuterState> for State<InnerState>

Review comment (suggestion):
I'm a little worried that people will do fine-grained locking where more coarse locking is the right solution, based on this example. I'm not sure just showing an `Arc<Mutex<_>>` with everything inside locked at once is better either though...

Code after:
///
/// In general however we recommend you implement `Clone` for all your state types to avoid
/// potential type errors.
///
/// # Shared mutable state
///
/// [As state is global within a `Router`][global] you can't directly get a mutable reference to
/// the state.
///
/// The most basic solution is to use an `Arc<Mutex<_>>`. Which kind of mutex you need depends on
/// your use case. See [the tokio docs] for more details.
///
/// Note that holding a locked `std::sync::Mutex` across `.await` points will result in `!Send`
/// futures which are incompatible with axum. If you need to hold a mutex across `.await` points,
/// consider using a `tokio::sync::Mutex` instead.
///
/// ## Example
///
/// ```
/// use axum::{Router, routing::get, extract::State};
/// use std::sync::{Arc, Mutex};
///
/// #[derive(Clone)]
/// struct AppState {
///     data: Arc<Mutex<String>>,
/// }
///
/// async fn handler(State(state): State<AppState>) {
///     let mut data = state.data.lock().expect("mutex was poisoned");
///     *data = "updated foo".to_owned();
///
///     // ...
/// }
///
/// let state = AppState {
///     data: Arc::new(Mutex::new("foo".to_owned())),
/// };
///
/// let app = Router::new()
///     .route("/", get(handler))
///     .with_state(state);
/// # let _: Router = app;
/// ```
///
/// [global]: crate::Router::with_state
/// [the tokio docs]: https://docs.rs/tokio/1.25.0/tokio/sync/struct.Mutex.html#which-kind-of-mutex-should-you-use
#[derive(Debug, Default, Clone, Copy)]
pub struct State<S>(pub S);

#[async_trait]
impl<OuterState, InnerState> FromRequestParts<OuterState> for State<InnerState>