doum_cli/core/
config.rs

1use crate::system::{load_config, load_default_config, save_config};
2use anyhow::Result;
3use std::{fmt::Display, str::FromStr};
4
5/// Get config value by key
6pub fn get_value(key: &str) -> Result<String> {
7    let config = load_config()?;
8
9    let value = match key {
10        "llm.provider" => config.llm.provider,
11        "llm.model" => config.llm.model,
12        "llm.timeout" => config.llm.timeout.to_string(),
13        "llm.max_retries" => config.llm.max_retries.to_string(),
14        "llm.use_thinking" => config.llm.use_thinking.to_string(),
15        "llm.use_web_search" => config.llm.use_web_search.to_string(),
16        "context.max_lines" => config.context.max_lines.to_string(),
17        "context.max_size_kb" => config.context.max_size_kb.to_string(),
18        "logging.enabled" => config.logging.enabled.to_string(),
19        "logging.level" => config.logging.level,
20        _ => {
21            anyhow::bail!("Unknown config key: {}", key);
22        }
23    };
24
25    Ok(value)
26}
27
28/// Set config value by key
29pub fn set_value(key: &str, value: &str) -> Result<()> {
30    let mut config = load_config()?;
31
32    match key {
33        "llm.provider" => {
34            config.llm.provider = value.to_string();
35        }
36        "llm.model" => {
37            config.llm.model = value.to_string();
38        }
39        "llm.timeout" => {
40            config.llm.timeout = parse_value(value, "timeout")?;
41        }
42        "llm.max_retries" => {
43            config.llm.max_retries = parse_value(value, "max_retries")?;
44        }
45        "llm.use_thinking" => {
46            config.llm.use_thinking = parse_value(value, "use_thinking")?;
47        }
48        "llm.use_web_search" => {
49            config.llm.use_web_search = parse_value(value, "use_web_search")?;
50        }
51        "context.max_lines" => {
52            config.context.max_lines = parse_value(value, "max_lines")?;
53        }
54        "context.max_size_kb" => {
55            config.context.max_size_kb = parse_value(value, "max_size_kb")?;
56        }
57        "logging.enabled" => {
58            config.logging.enabled = parse_value(value, "logging.enabled")?;
59        }
60        "logging.level" => {
61            config.logging.level = value.to_string();
62        }
63        _ => {
64            anyhow::bail!("Unknown config key: {}", key);
65        }
66    }
67
68    save_config(&config)?;
69    Ok(())
70}
71
72/// Unset a key (restore to default)
73pub fn unset_value(key: &str) -> Result<()> {
74    let default_config = load_default_config()?;
75    let mut config = load_config()?;
76
77    match key {
78        "llm.provider" => config.llm.provider = default_config.llm.provider,
79        "llm.model" => config.llm.model = default_config.llm.model,
80        "llm.timeout" => config.llm.timeout = default_config.llm.timeout,
81        "llm.max_retries" => config.llm.max_retries = default_config.llm.max_retries,
82        "llm.use_thinking" => config.llm.use_thinking = default_config.llm.use_thinking,
83        "llm.use_web_search" => config.llm.use_web_search = default_config.llm.use_web_search,
84        "context.max_lines" => config.context.max_lines = default_config.context.max_lines,
85        "context.max_size_kb" => config.context.max_size_kb = default_config.context.max_size_kb,
86        "logging.enabled" => config.logging.enabled = default_config.logging.enabled,
87        "logging.level" => config.logging.level = default_config.logging.level,
88        _ => {
89            anyhow::bail!("Unknown config key: {}", key);
90        }
91    }
92
93    save_config(&config)?;
94    Ok(())
95}
96
97/// Reset config to defaults
98pub fn reset() -> Result<()> {
99    let default_config = load_default_config()?;
100    save_config(&default_config)
101}
102
103/// Get all config as TOML string
104pub fn get_all_as_str() -> Result<String> {
105    let config = load_config()?;
106    toml::to_string_pretty(&config)
107        .map_err(|e| anyhow::anyhow!("Failed to serialize config to TOML: {}", e))
108}
109
110fn parse_value<T: FromStr>(value: &str, field_name: &str) -> Result<T>
111where
112    T::Err: Display,
113{
114    value
115        .parse()
116        .map_err(|e| anyhow::anyhow!("Invalid {} value: {} - {}", field_name, value, e))
117}