cja/
app_state.rs

1use crate::server::cookies::CookieKey;
2
3/// A trait representing the application state that must be implemented by users of the cja framework.
4///
5/// This trait provides access to core components like the database pool and cookie encryption key.
6/// The `AppState` is cloned for each request, so it should be cheap to clone (usually by wrapping
7/// expensive resources in Arc).
8///
9/// # Example
10///
11/// ```rust
12/// use cja::app_state::AppState;
13/// use cja::server::cookies::CookieKey;
14/// use sqlx::PgPool;
15///
16/// #[derive(Clone)]
17/// struct MyAppState {
18///     db: PgPool,
19///     cookie_key: CookieKey,
20/// }
21///
22/// impl AppState for MyAppState {
23///     fn version(&self) -> &str {
24///         "1.0.0"
25///     }
26///     
27///     fn db(&self) -> &PgPool {
28///         &self.db
29///     }
30///     
31///     fn cookie_key(&self) -> &CookieKey {
32///         &self.cookie_key
33///     }
34/// }
35/// ```
36///
37/// # Using with Axum
38///
39/// ```rust
40/// use cja::app_state::AppState;
41/// use cja::server::cookies::CookieKey;
42/// use sqlx::postgres::PgPoolOptions;
43/// use axum::{Router, routing::get, extract::State};
44///
45/// #[derive(Clone)]
46/// struct MyAppState {
47///     db: sqlx::PgPool,
48///     cookie_key: CookieKey,
49/// }
50///
51/// impl AppState for MyAppState {
52///     fn version(&self) -> &str { "1.0.0" }
53///     fn db(&self) -> &sqlx::PgPool { &self.db }
54///     fn cookie_key(&self) -> &CookieKey { &self.cookie_key }
55/// }
56///
57/// async fn handler(State(state): State<MyAppState>) -> String {
58///     format!("App version: {}", state.version())
59/// }
60///
61///  async fn example() -> Result<(), Box<dyn std::error::Error>> {
62///  use sqlx::postgres::PgPoolOptions;
63/// let db = PgPoolOptions::new()
64///      .connect(&std::env::var("DATABASE_URL").unwrap_or_else(|_| "postgres://test".to_string()))
65///      .await
66///      .map_err(|_| "Database connection failed")?;
67///     
68/// let state = MyAppState {
69///     db,
70///     cookie_key: CookieKey::from_env_or_generate()?,
71/// };
72///
73/// let app: Router = Router::new()
74///     .route("/", get(handler))
75///     .with_state(state);
76///
77/// // Run the server
78/// # Ok(())
79/// # }
80/// ```
81pub trait AppState: Clone + Send + Sync + 'static {
82    /// Returns the version string for the application.
83    /// This is useful for health checks and debugging.
84    fn version(&self) -> &str;
85
86    /// Returns a reference to the database connection pool.
87    /// The pool is typically shared across all requests.
88    fn db(&self) -> &sqlx::PgPool;
89
90    /// Returns the cookie encryption key used for secure cookies.
91    /// This key should be consistent across application restarts
92    /// to maintain session continuity.
93    fn cookie_key(&self) -> &CookieKey;
94}