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}