use std::{fs, io, path::PathBuf}; use super::paths; #[derive(Debug, Clone)] pub struct Config { pub base_url: String, pub access_token: Option, pub user_id: Option, pub transcode_mbps: f32, } #[derive(Debug)] pub enum ConfigError { NotFound(PathBuf), Io(io::Error), Parse(String), } impl From for ConfigError { fn from(e: io::Error) -> Self { Self::Io(e) } } pub fn config_path() -> Option { paths::app_config_dir().map(|d| d.join("config.toml")) } // Very small TOML-ish parser for now (no deps). // Format: // base_url = "http://..." // access_token = "..." pub fn load_config() -> Result { let path = config_path().ok_or_else(|| ConfigError::Parse("No HOME/XDG dirs".into()))?; if !path.exists() { return Err(ConfigError::NotFound(path)); } let s = fs::read_to_string(&path)?; parse_config(&s).map_err(ConfigError::Parse) } fn parse_config(s: &str) -> Result { let mut base_url: Option = None; let mut access_token: Option = None; let mut user_id: Option = None; let mut transcode_mbps: Option = None; for (i, line) in s.lines().enumerate() { let line = line.trim(); if line.is_empty() || line.starts_with('#') { continue; } let (k, v) = line .split_once('=') .ok_or_else(|| format!("Line {}: expected key = value", i + 1))?; let key = k.trim(); let mut val = v.trim().to_string(); // strip quotes if present if val.starts_with('"') && val.ends_with('"') && val.len() >= 2 { val = val[1..val.len() - 1].to_string(); } match key { "base_url" => base_url = Some(val), "access_token" => access_token = Some(val), "user_id" => user_id = Some(val), "transcode_mbps" => { // allow raw numbers or quoted numbers if let Ok(n) = val.parse::() { transcode_mbps = Some(n); } } _ => {} } } let base_url = base_url.ok_or_else(|| "Missing base_url".to_string())?; Ok(Config { base_url, access_token, user_id, transcode_mbps: transcode_mbps.unwrap_or(5.0), }) } pub fn save_config(cfg: &Config) -> Result<(), ConfigError> { let dir = paths::app_config_dir() .ok_or_else(|| ConfigError::Parse("No HOME/XDG dirs".into()))?; std::fs::create_dir_all(&dir)?; let path = dir.join("config.toml"); let mut out = String::new(); out.push_str(&format!("base_url = \"{}\"\n", cfg.base_url)); if let Some(t) = &cfg.access_token { out.push_str(&format!("access_token = \"{}\"\n", t)); } if let Some(u) = &cfg.user_id { out.push_str(&format!("user_id = \"{}\"\n", u)); } out.push_str(&format!("transcode_mbps = {}\n", cfg.transcode_mbps)); std::fs::write(path, out)?; Ok(()) }