summaryrefslogtreecommitdiff
path: root/src/config.rs
diff options
context:
space:
mode:
authorDawid Rycerz <dawid@rycerz.xyz>2025-07-21 21:10:22 +0300
committerDawid Rycerz <dawid@rycerz.xyz>2025-07-21 21:10:22 +0300
commit934fb31059da10fa843d96a10c37f181eaa89456 (patch)
tree452b36bdd1e286e68381607f15742695afec0f60 /src/config.rs
parent30f50e5b31294abd75c4b629970ad4865108738d (diff)
feat: add weather pooler and config
Diffstat (limited to 'src/config.rs')
-rw-r--r--src/config.rs160
1 files changed, 160 insertions, 0 deletions
diff --git a/src/config.rs b/src/config.rs
new file mode 100644
index 0000000..186ef82
--- /dev/null
+++ b/src/config.rs
@@ -0,0 +1,160 @@
+use std::env;
+use std::path::PathBuf;
+
+#[derive(Debug, Clone)]
+pub struct Config {
+ pub database_url: String,
+ #[allow(dead_code)]
+ pub openweathermap_api_key: Option<String>,
+ pub admin_token: Option<String>,
+ pub server_port: u16,
+ pub server_host: String,
+ pub log_level: String,
+}
+
+impl Config {
+ pub fn from_env() -> Self {
+ let database_url = Self::get_database_url();
+ let openweathermap_api_key = env::var("OPENWEATHERMAP_API_KEY").ok();
+ let admin_token = env::var("ADMIN_TOKEN").ok();
+ let server_port = env::var("PORT")
+ .unwrap_or_else(|_| "4000".to_string())
+ .parse()
+ .unwrap_or(4000);
+ let server_host = env::var("HOST").unwrap_or_else(|_| "0.0.0.0".to_string());
+ let log_level = env::var("LOG_LEVEL").unwrap_or_else(|_| "info".to_string());
+
+ Self {
+ database_url,
+ openweathermap_api_key,
+ admin_token,
+ server_port,
+ server_host,
+ log_level,
+ }
+ }
+
+ fn get_database_url() -> String {
+ // First, check if DATABASE_URL is explicitly set
+ if let Ok(url) = env::var("DATABASE_URL") {
+ return url;
+ }
+
+ // If not set, construct the path using XDG_DATA_HOME or fallback
+ let data_dir = if let Ok(xdg_data_home) = env::var("XDG_DATA_HOME") {
+ PathBuf::from(xdg_data_home)
+ } else {
+ // Fallback to ~/.local/share
+ let home = env::var("HOME")
+ .unwrap_or_else(|_| env::var("USERPROFILE").unwrap_or_else(|_| "/tmp".to_string()));
+ PathBuf::from(home).join(".local").join("share")
+ };
+
+ let db_path = data_dir.join("silmataivas").join("silmataivas.db");
+
+ // Ensure the directory exists
+ if let Some(parent) = db_path.parent() {
+ let _ = std::fs::create_dir_all(parent);
+ }
+
+ format!("sqlite://{}", db_path.display())
+ }
+
+ #[allow(dead_code)]
+ pub fn validate(&self) -> Result<(), String> {
+ if self.openweathermap_api_key.is_none() {
+ return Err("OPENWEATHERMAP_API_KEY environment variable is required".to_string());
+ }
+ Ok(())
+ }
+
+ #[allow(dead_code)]
+ pub fn validate_optional(&self) -> Result<(), String> {
+ // For optional validation (e.g., during development)
+ Ok(())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use std::env;
+ use std::sync::Once;
+
+ static INIT: Once = Once::new();
+
+ fn setup() {
+ INIT.call_once(|| {
+ // Clear all environment variables that might interfere with tests
+ unsafe {
+ env::remove_var("DATABASE_URL");
+ env::remove_var("XDG_DATA_HOME");
+ env::remove_var("PORT");
+ env::remove_var("HOST");
+ env::remove_var("LOG_LEVEL");
+ }
+ });
+
+ // Clear environment variables before each test
+ unsafe {
+ env::remove_var("DATABASE_URL");
+ env::remove_var("XDG_DATA_HOME");
+ env::remove_var("PORT");
+ env::remove_var("HOST");
+ env::remove_var("LOG_LEVEL");
+ }
+ }
+
+ #[test]
+ fn test_database_url_fallback() {
+ setup();
+
+ let home = env::var("HOME").unwrap_or_else(|_| "/tmp".to_string());
+ let expected_path = format!("sqlite://{home}/.local/share/silmataivas/silmataivas.db");
+
+ let config = Config::from_env();
+ assert_eq!(config.database_url, expected_path);
+ }
+
+ #[test]
+ fn test_database_url_xdg_data_home() {
+ setup();
+
+ unsafe {
+ env::set_var("XDG_DATA_HOME", "/custom/data/path");
+ }
+
+ let expected_path = "sqlite:///custom/data/path/silmataivas/silmataivas.db";
+
+ let config = Config::from_env();
+ assert_eq!(config.database_url, expected_path);
+ }
+
+ #[test]
+ fn test_database_url_explicit() {
+ setup();
+
+ unsafe {
+ env::set_var("DATABASE_URL", "sqlite:///explicit/path.db");
+ }
+
+ let config = Config::from_env();
+ assert_eq!(config.database_url, "sqlite:///explicit/path.db");
+ }
+
+ #[test]
+ fn test_server_config() {
+ setup();
+
+ unsafe {
+ env::set_var("PORT", "8080");
+ env::set_var("HOST", "127.0.0.1");
+ env::set_var("LOG_LEVEL", "debug");
+ }
+
+ let config = Config::from_env();
+ assert_eq!(config.server_port, 8080);
+ assert_eq!(config.server_host, "127.0.0.1");
+ assert_eq!(config.log_level, "debug");
+ }
+}