use serde::Deserialize; use std::env; use std::path::PathBuf; use toml::Value; use tracing::{error, info}; #[derive(Deserialize, Debug)] pub struct AppSettings { pub config_path: String, pub db_path: String, pub migration_path: String, pub config: Config, } #[derive(Deserialize, Debug)] pub struct Config { pub server: Server, } #[derive(Deserialize, Debug)] pub struct Server { pub host: String, pub port: u16, } #[derive(Deserialize, Debug)] struct ConfigFile { server: Server, } impl AppSettings { pub fn get_app_settings() -> Self { let config_file = Self::load_config_file().unwrap_or_else(|| { info!("Using default config values"); ConfigFile { server: Server { host: "127.0.0.1".to_string(), port: 1337, }, } }); Self { config_path: Self::get_config_path(), db_path: Self::get_db_path(), migration_path: String::from("./migrations"), config: Config { server: config_file.server, }, } } fn load_config_file() -> Option { let config_path = Self::get_config_path(); let contents = std::fs::read_to_string(&config_path) .map_err(|e| error!("Failed to read config file: {}", e)) .ok()?; toml::from_str(&contents) .map_err(|e| error!("Failed to parse TOML: {}", e)) .ok() } fn get_db_path() -> String { if cfg!(debug_assertions) { // Development: Use backend-rust directory // TODO: Change later let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); path.push("owlynews.sqlite3"); path.to_str().unwrap().to_string() } else { // Production: Use standard Linux applications data directory "/var/lib/owly-news-summariser/owlynews.sqlite3".to_string() } } fn get_config_path() -> String { if cfg!(debug_assertions) { // Development: Use backend-rust directory // TODO: Change later let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); path.push("config.toml"); path.to_str().unwrap().to_string() } else { // Production: Use standard Linux applications data directory "$HOME/owly-news-summariser/config.toml".to_string() } } pub fn database_url(&self) -> String { format!("sqlite:{}", self.db_path) } pub fn ensure_db_directory(&self) -> Result<(), std::io::Error> { if let Some(parent) = std::path::Path::new(&self.db_path).parent() { std::fs::create_dir_all(parent)?; } Ok(()) } }