ferrite_cli/
lib.rs

1use clap::Parser;
2use ferrite_config::FerriteConfig;
3use ferrite_logging::LogLevel;
4use std::{env, path::PathBuf};
5use thiserror::Error;
6
7#[derive(Error, Debug)]
8pub enum CliError {
9    #[error("Configuration error: {0}")]
10    Config(#[from] ferrite_config::ConfigError),
11
12    #[error("Invalid log level: {0}")]
13    LogLevel(String),
14
15    #[error("Invalid path: {path}")]
16    InvalidPath { path: PathBuf },
17
18    #[error("Failed to generate config: {0}")]
19    ConfigGeneration(String),
20}
21
22pub type Result<T> = std::result::Result<T, CliError>;
23
24#[derive(Parser, Debug)]
25#[command(
26    author,
27    version,
28    about = "Ferrite - A fast and efficient image viewer"
29)]
30pub struct Args {
31    /// Initial image file to open
32    #[arg(value_name = "IMAGE")]
33    pub image_path: Option<PathBuf>,
34
35    /// Set the logging level
36    #[arg(long, value_name = "LEVEL", default_value = "info")]
37    pub log_level: Option<String>,
38
39    /// Generate a default configuration file
40    #[arg(long)]
41    pub generate_config: bool,
42}
43
44impl Args {
45    pub fn parse() -> Self {
46        <Self as clap::Parser>::parse()
47    }
48
49    pub fn get_log_level(&self) -> Result<LogLevel> {
50        match &self.log_level {
51            Some(level) => level.parse().map_err(|e| CliError::LogLevel(e)),
52            None => Ok(LogLevel::Info),
53        }
54    }
55
56    pub fn handle_config(&self) -> Result<FerriteConfig> {
57        if self.generate_config {
58            let config_path = FerriteConfig::resolve_config_path()?;
59            println!(
60                "Generating default configuration at: {}",
61                config_path.display()
62            );
63            let config = FerriteConfig::default();
64            config.save_to_path(&config_path)?;
65
66            // Print helpful information about configuration
67            println!("\nConfiguration can be customized by:");
68            println!(
69                "1. Editing the file directly at: {}",
70                config_path.display()
71            );
72            println!(
73                "2. Setting FERRITE_CONF environment variable for a different \
74                 location"
75            );
76            println!("\nExample environment variable usage:");
77            println!(
78                "export FERRITE_CONF=$HOME/.config/ferrite/custom-config.toml"
79            );
80
81            std::process::exit(0);
82        }
83
84        Ok(FerriteConfig::load()?)
85    }
86
87    pub fn print_config_info(&self) -> Result<()> {
88        let config_path = FerriteConfig::resolve_config_path()?;
89
90        println!("\nFerrite Configuration");
91        println!("--------------------");
92        println!("Current config path: {}", config_path.display());
93        println!("\nConfiguration path is determined by:");
94        println!("1. FERRITE_CONF environment variable (if set)");
95        println!("2. Default system-specific location");
96
97        if let Ok(env_path) = env::var("FERRITE_CONF") {
98            println!("\nFERRITE_CONF is currently set to: {}", env_path);
99        }
100
101        let default_path = FerriteConfig::get_default_path()?;
102        println!("Default path: {}", default_path.display());
103
104        Ok(())
105    }
106}