diff --git a/.gitignore b/.gitignore index b3dab35..f08a1bd 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ target # option (not recommended) you can uncomment the following to ignore the entire idea folder. #.idea/ Cargo.lock +.DS_Store diff --git a/src/main.rs b/src/main.rs index b26e293..4c9e510 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,13 @@ use anyhow::{Context, Result}; use clap::Parser; use serde::Deserialize; +use std::collections::HashMap; use std::fs; use std::path::Path; use std::process::Command; use tempfile::TempDir; -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, Clone)] struct Settings { nas_host: String, nas_user: String, @@ -14,12 +15,21 @@ struct Settings { cookies_file: String, } +#[derive(Debug, Deserialize)] +struct AppConfig { + profiles: HashMap, +} + #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] struct Args { /// The URL of the video/music to download #[arg(name = "URL")] url: String, + + /// Profile name to use from config (falls back to 'default') + #[arg(short, long, default_value = "default")] + profile: String, } fn main() -> Result<()> { @@ -48,10 +58,37 @@ fn main() -> Result<()> { println!("[INFO] Using config file at: {}", config_path.display()); - let settings = config::Config::builder() - .add_source(config::File::from(config_path)) - .build()? - .try_deserialize::()?; + let cfg = config::Config::builder() + .add_source(config::File::from(config_path.clone())) + .build()?; + + let selected_profile = args.profile.clone(); + let settings: Settings = match cfg.clone().try_deserialize::() { + Ok(app_cfg) => { + if let Some(s) = app_cfg.profiles.get(&selected_profile).cloned() { + println!("[INFO] Using profile: {}", selected_profile); + s + } else if let Some(s) = app_cfg.profiles.get("default").cloned() { + if selected_profile != "default" { + println!("[WARN] Profile '{}' not found. Falling back to 'default'.", selected_profile); + let available = app_cfg.profiles.keys().cloned().collect::>().join(", "); + println!("[INFO] Available profiles: {}", available); + } else { + println!("[INFO] Using profile: default"); + } + s + } else { + anyhow::bail!("No profile '{}' found and no 'default' profile defined in config.", selected_profile); + } + } + Err(_) => { + if selected_profile != "default" { + println!("[WARN] Requested profile '{}' but config file uses single-profile format. Using that single profile.", selected_profile); + } + println!("[INFO] Using legacy single-profile configuration."); + cfg.try_deserialize::()? + } + }; // Create temp directory let temp_dir = TempDir::new().context("Failed to create temporary directory")?;