Skip to main content

anvil_core/
config.rs

1//! Configuration loading. `.env` via dotenvy + typed config structs in `config/*.rs`.
2
3use std::env;
4
5pub fn load_dotenv() {
6    let _ = dotenvy::dotenv();
7}
8
9#[derive(Debug, Clone)]
10pub struct AppConfig {
11    pub name: String,
12    pub env: String,
13    pub key: String,
14    pub debug: bool,
15    pub url: String,
16}
17
18impl AppConfig {
19    pub fn from_env() -> Self {
20        Self {
21            name: env::var("APP_NAME").unwrap_or_else(|_| "Anvil".to_string()),
22            env: env::var("APP_ENV").unwrap_or_else(|_| "production".to_string()),
23            key: env::var("APP_KEY").unwrap_or_default(),
24            debug: env::var("APP_DEBUG")
25                .ok()
26                .and_then(|v| v.parse().ok())
27                .unwrap_or(false),
28            url: env::var("APP_URL").unwrap_or_else(|_| "http://localhost:8080".to_string()),
29        }
30    }
31
32    pub fn is_local(&self) -> bool {
33        self.env == "local" || self.env == "development"
34    }
35}
36
37#[derive(Debug, Clone)]
38pub struct DatabaseConfig {
39    pub url: String,
40    pub pool_size: u32,
41}
42
43impl DatabaseConfig {
44    pub fn from_env() -> Self {
45        Self {
46            url: env::var("DATABASE_URL").unwrap_or_else(|_| {
47                "postgres://postgres:postgres@localhost:5432/anvil".to_string()
48            }),
49            pool_size: env::var("DB_POOL")
50                .ok()
51                .and_then(|v| v.parse().ok())
52                .unwrap_or(10),
53        }
54    }
55}
56
57#[derive(Debug, Clone)]
58pub struct SessionConfig {
59    pub driver: String,
60    pub lifetime_minutes: i64,
61    pub cookie_name: String,
62    pub same_site: String,
63    pub secure: bool,
64}
65
66impl SessionConfig {
67    pub fn from_env() -> Self {
68        Self {
69            driver: env::var("SESSION_DRIVER").unwrap_or_else(|_| "file".to_string()),
70            lifetime_minutes: env::var("SESSION_LIFETIME")
71                .ok()
72                .and_then(|v| v.parse().ok())
73                .unwrap_or(120),
74            cookie_name: env::var("SESSION_COOKIE").unwrap_or_else(|_| "anvil_session".to_string()),
75            same_site: env::var("SESSION_SAME_SITE").unwrap_or_else(|_| "lax".to_string()),
76            secure: env::var("SESSION_SECURE")
77                .ok()
78                .and_then(|v| v.parse().ok())
79                .unwrap_or(false),
80        }
81    }
82}
83
84#[derive(Debug, Clone)]
85pub struct CacheConfig {
86    pub driver: String,
87    pub ttl_seconds: u64,
88}
89
90impl CacheConfig {
91    pub fn from_env() -> Self {
92        Self {
93            driver: env::var("CACHE_DRIVER").unwrap_or_else(|_| "moka".to_string()),
94            ttl_seconds: env::var("CACHE_TTL")
95                .ok()
96                .and_then(|v| v.parse().ok())
97                .unwrap_or(3600),
98        }
99    }
100}
101
102#[derive(Debug, Clone)]
103pub struct QueueConfig {
104    pub driver: String,
105    pub default_queue: String,
106}
107
108impl QueueConfig {
109    pub fn from_env() -> Self {
110        Self {
111            driver: env::var("QUEUE_DRIVER").unwrap_or_else(|_| "database".to_string()),
112            default_queue: env::var("QUEUE_DEFAULT").unwrap_or_else(|_| "default".to_string()),
113        }
114    }
115}
116
117#[derive(Debug, Clone)]
118pub struct MailConfig {
119    pub mailer: String,
120    pub host: String,
121    pub port: u16,
122    pub username: String,
123    pub password: String,
124    pub from_address: String,
125    pub from_name: String,
126}
127
128impl MailConfig {
129    pub fn from_env() -> Self {
130        Self {
131            mailer: env::var("MAIL_MAILER").unwrap_or_else(|_| "smtp".to_string()),
132            host: env::var("MAIL_HOST").unwrap_or_else(|_| "localhost".to_string()),
133            port: env::var("MAIL_PORT")
134                .ok()
135                .and_then(|v| v.parse().ok())
136                .unwrap_or(1025),
137            username: env::var("MAIL_USERNAME").unwrap_or_default(),
138            password: env::var("MAIL_PASSWORD").unwrap_or_default(),
139            from_address: env::var("MAIL_FROM_ADDRESS")
140                .unwrap_or_else(|_| "hello@example.com".to_string()),
141            from_name: env::var("MAIL_FROM_NAME").unwrap_or_else(|_| "Anvil".to_string()),
142        }
143    }
144}
145
146#[derive(Debug, Clone)]
147pub struct FilesystemConfig {
148    pub default_disk: String,
149    pub local_root: String,
150}
151
152impl FilesystemConfig {
153    pub fn from_env() -> Self {
154        Self {
155            default_disk: env::var("FILESYSTEM_DISK").unwrap_or_else(|_| "local".to_string()),
156            local_root: env::var("FILESYSTEM_LOCAL_ROOT")
157                .unwrap_or_else(|_| "storage/app".to_string()),
158        }
159    }
160}