arc_web/helpers/
config.rs1use std::env;
2
3pub const DEFAULT_DATABASE_URL: &str = "database/database.sqlite";
5
6pub const DEFAULT_SESSION_DATABASE_URL: &str = "database/sessions.sqlite";
9
10pub const DEFAULT_POOL_LIMIT: u32 = 10;
12
13pub const DEFAULT_USER_SNAPSHOT_INTERVAL_EVENTS: i64 = 50;
15
16#[derive(Clone, Copy, Debug, PartialEq, Eq)]
20pub enum DatabaseDriver {
21 Sqlite,
22 Postgres,
23}
24
25impl DatabaseDriver {
26 pub fn from_env() -> Self {
28 Self::parse(&env::var("DATABASE_DRIVER").unwrap_or_else(|_| "sqlite".to_string()))
29 }
30
31 pub fn parse(value: &str) -> Self {
34 match value.trim().to_ascii_lowercase().as_str() {
35 "postgres" | "postgresql" | "pg" => DatabaseDriver::Postgres,
36 _ => DatabaseDriver::Sqlite,
37 }
38 }
39
40 pub fn as_str(self) -> &'static str {
41 match self {
42 DatabaseDriver::Sqlite => "sqlite",
43 DatabaseDriver::Postgres => "postgres",
44 }
45 }
46
47 pub fn is_file_backed(self) -> bool {
50 matches!(self, DatabaseDriver::Sqlite)
51 }
52}
53
54pub fn database_url() -> String {
56 env::var("DATABASE_URL").unwrap_or_else(|_| DEFAULT_DATABASE_URL.to_string())
57}
58
59pub fn session_store_url(driver: DatabaseDriver) -> String {
64 match driver {
65 DatabaseDriver::Sqlite => database_url(),
66 DatabaseDriver::Postgres => env::var("SESSION_DATABASE_URL")
67 .unwrap_or_else(|_| DEFAULT_SESSION_DATABASE_URL.to_string()),
68 }
69}
70
71pub fn event_integrity_key() -> Option<Vec<u8>> {
74 env::var("EVENT_INTEGRITY_KEY")
75 .ok()
76 .filter(|value| !value.trim().is_empty())
77 .map(|value| value.into_bytes())
78}
79
80pub fn event_integrity_key_id() -> String {
83 env::var("EVENT_INTEGRITY_KEY_ID").unwrap_or_else(|_| "default".to_string())
84}
85
86pub fn user_snapshot_interval_events() -> Option<i64> {
89 let interval = env::var("USER_SNAPSHOT_INTERVAL_EVENTS")
90 .ok()
91 .filter(|value| !value.trim().is_empty())
92 .map(|value| {
93 value
94 .parse()
95 .expect("USER_SNAPSHOT_INTERVAL_EVENTS must be a number")
96 })
97 .unwrap_or(DEFAULT_USER_SNAPSHOT_INTERVAL_EVENTS);
98
99 (interval > 0).then_some(interval)
100}
101
102pub fn database_pool_limit() -> u32 {
104 env::var("DATABASE_POOL_LIMIT")
105 .unwrap_or_else(|_| DEFAULT_POOL_LIMIT.to_string())
106 .parse()
107 .expect("DATABASE_POOL_LIMIT must be a number")
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113 use serial_test::serial;
114
115 #[test]
116 #[serial]
117 fn user_snapshot_interval_defaults_to_50() {
118 env::remove_var("USER_SNAPSHOT_INTERVAL_EVENTS");
119 assert_eq!(
120 user_snapshot_interval_events(),
121 Some(DEFAULT_USER_SNAPSHOT_INTERVAL_EVENTS)
122 );
123 }
124
125 #[test]
126 #[serial]
127 fn user_snapshot_interval_reads_env_override() {
128 env::set_var("USER_SNAPSHOT_INTERVAL_EVENTS", "25");
129 assert_eq!(user_snapshot_interval_events(), Some(25));
130 env::remove_var("USER_SNAPSHOT_INTERVAL_EVENTS");
131 }
132
133 #[test]
134 #[serial]
135 fn user_snapshot_interval_non_positive_disables_snapshots() {
136 env::set_var("USER_SNAPSHOT_INTERVAL_EVENTS", "0");
137 assert_eq!(user_snapshot_interval_events(), None);
138 env::remove_var("USER_SNAPSHOT_INTERVAL_EVENTS");
139 }
140}