Skip to main content

atrg_core/
state.rs

1//! Application state shared across all Axum handlers.
2
3use std::sync::Arc;
4
5use sqlx::SqlitePool;
6
7use crate::config::Config;
8use atrg_identity::IdentityResolver;
9
10/// Shared application state passed to every Axum handler.
11///
12/// This is the central state object that every route handler receives via
13/// `axum::extract::State<AppState>`. It holds the parsed configuration,
14/// database connection pool, and a shared HTTP client for outbound requests.
15///
16/// `AppState` is cheaply cloneable — all inner fields are either `Arc`-wrapped
17/// or already use internal reference counting (e.g. `SqlitePool`, `reqwest::Client`).
18#[derive(Clone)]
19pub struct AppState {
20    /// Parsed configuration from `atrg.toml`.
21    pub config: Arc<Config>,
22    /// SQLite connection pool.
23    pub db: SqlitePool,
24    /// Shared HTTP client for outbound requests.
25    pub http: reqwest::Client,
26    /// DID/handle resolver with TTL-backed in-memory cache.
27    pub identity: Arc<IdentityResolver>,
28}
29
30// ---------------------------------------------------------------------------
31// FromRef implementations — allow Axum sub-extractors to pull individual
32// fields out of AppState without the handler needing to destructure manually.
33// ---------------------------------------------------------------------------
34
35impl axum::extract::FromRef<AppState> for SqlitePool {
36    fn from_ref(state: &AppState) -> Self {
37        state.db.clone()
38    }
39}
40
41impl axum::extract::FromRef<AppState> for Arc<Config> {
42    fn from_ref(state: &AppState) -> Self {
43        state.config.clone()
44    }
45}
46
47impl axum::extract::FromRef<AppState> for Arc<IdentityResolver> {
48    fn from_ref(state: &AppState) -> Self {
49        state.identity.clone()
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    // Compile-time assertion helper.
58    fn _assert_send_sync_clone<T: Send + Sync + Clone>() {}
59
60    #[test]
61    fn app_state_is_send_sync_clone() {
62        _assert_send_sync_clone::<AppState>();
63    }
64}