Skip to main content

invoice_cli/commands/
config.rs

1use crate::cli::ConfigCmd;
2use crate::config;
3use crate::error::{AppError, Result};
4use crate::output::{print_success, Ctx};
5
6pub fn run(cmd: ConfigCmd, ctx: Ctx) -> Result<()> {
7    match cmd {
8        ConfigCmd::Show => {
9            let cfg = config::load()?;
10            print_success(ctx, &cfg, |c| println!("{:#?}", c));
11            Ok(())
12        }
13        ConfigCmd::Path => {
14            let p = config::config_path()?;
15            print_success(ctx, &p, |p| println!("{}", p.display()));
16            Ok(())
17        }
18        ConfigCmd::Set { key, value } => {
19            // Minimal implementation: set-and-save via toml::Value merge.
20            let path = config::config_path()?;
21            let existing = if path.exists() {
22                std::fs::read_to_string(&path)?
23            } else {
24                String::new()
25            };
26            let mut doc: toml::Value = toml::from_str(&existing).unwrap_or(toml::Value::Table(Default::default()));
27            if let toml::Value::Table(ref mut t) = doc {
28                t.insert(key.clone(), parse_value(&value));
29            } else {
30                return Err(AppError::Config("config root is not a table".into()));
31            }
32            std::fs::write(&path, toml::to_string_pretty(&doc).unwrap())?;
33            print_success(ctx, &serde_json::json!({"key": key, "value": value}), |_| {
34                println!("set {} = {}", key, value)
35            });
36            Ok(())
37        }
38    }
39}
40
41fn parse_value(v: &str) -> toml::Value {
42    if v == "true" {
43        toml::Value::Boolean(true)
44    } else if v == "false" {
45        toml::Value::Boolean(false)
46    } else if let Ok(n) = v.parse::<i64>() {
47        toml::Value::Integer(n)
48    } else {
49        toml::Value::String(v.to_string())
50    }
51}