Skip to main content

reposix_sim/
state.rs

1//! Shared application state for the simulator's axum handlers.
2//!
3//! Holds the single `SQLite` [`rusqlite::Connection`] behind a
4//! [`parking_lot::Mutex`] (the whole connection is the critical section — we
5//! never hold the lock across `.await`), plus an [`Arc<SimConfig>`] so every
6//! request can see the bind address / rate-limit settings without a global.
7
8use std::sync::Arc;
9
10use parking_lot::Mutex;
11use rusqlite::Connection;
12
13use crate::SimConfig;
14
15/// Application state shared with every axum handler and middleware.
16///
17/// Cloning an [`AppState`] is cheap: it is two `Arc` bumps. Handlers receive
18/// it via `axum::extract::State(AppState)` thanks to `Router::with_state`.
19#[derive(Clone)]
20pub struct AppState {
21    /// Single global `SQLite` connection. Lock scope is always synchronous
22    /// (never across `.await`) so the mutex never stalls the tokio runtime.
23    pub db: Arc<Mutex<Connection>>,
24    /// Runtime configuration, shared read-only.
25    pub config: Arc<SimConfig>,
26}
27
28impl AppState {
29    /// Construct a new state from a ready-to-use connection and config.
30    #[must_use]
31    pub fn new(conn: Connection, config: SimConfig) -> Self {
32        Self {
33            db: Arc::new(Mutex::new(conn)),
34            config: Arc::new(config),
35        }
36    }
37}