ricecoder_cli/commands/
config.rs1use super::Command;
5use crate::error::{CliError, CliResult};
6use crate::output::OutputStyle;
7use std::collections::HashMap;
8use std::path::PathBuf;
9
10pub struct ConfigCommand {
12 pub action: ConfigAction,
13}
14
15#[derive(Debug, Clone)]
16pub enum ConfigAction {
17 List,
18 Get(String),
19 Set(String, String),
20}
21
22impl ConfigCommand {
23 pub fn new(action: ConfigAction) -> Self {
24 Self { action }
25 }
26
27 fn get_config_dir() -> CliResult<PathBuf> {
29 if let Ok(path) = std::env::var("RICECODER_HOME") {
31 return Ok(PathBuf::from(path));
32 }
33
34 if let Some(home) = dirs::home_dir() {
36 return Ok(home.join(".ricecoder"));
37 }
38
39 Err(CliError::Config(
40 "Could not determine configuration directory".to_string(),
41 ))
42 }
43
44 fn load_config() -> CliResult<HashMap<String, String>> {
46 let mut config = HashMap::new();
47
48 config.insert("provider.default".to_string(), "openai".to_string());
50 config.insert("storage.mode".to_string(), "merged".to_string());
51 config.insert("chat.history".to_string(), "true".to_string());
52 config.insert("output.colors".to_string(), "auto".to_string());
53
54 Ok(config)
58 }
59
60 fn list_config(&self) -> CliResult<()> {
62 let style = OutputStyle::default();
63 let config = Self::load_config()?;
64
65 println!("{}", style.header("RiceCoder Configuration"));
66 println!();
67
68 let mut keys: Vec<_> = config.keys().collect();
69 keys.sort();
70
71 for key in keys {
72 let value = &config[key];
73 println!(" {} = {}", style.code(key), value);
74 }
75
76 println!();
77 let config_dir = Self::get_config_dir()?;
78 println!(
79 "{}",
80 style.info(&format!("Config directory: {}", config_dir.display()))
81 );
82
83 Ok(())
84 }
85
86 fn get_config(&self, key: &str) -> CliResult<()> {
88 let style = OutputStyle::default();
89 let config = Self::load_config()?;
90
91 match config.get(key) {
92 Some(value) => {
93 println!("{} = {}", style.code(key), value);
94 Ok(())
95 }
96 None => {
97 println!(
98 "{}",
99 style.warning(&format!("Configuration key not found: {}", key))
100 );
101 println!(
102 "{}",
103 style.info("Run 'rice config' to see all available keys")
104 );
105 Ok(())
106 }
107 }
108 }
109
110 fn set_config(&self, key: &str, value: &str) -> CliResult<()> {
112 let style = OutputStyle::default();
113
114 println!("{}", style.success(&format!("Set {} = {}", key, value)));
118 println!(
119 "{}",
120 style.info("Configuration changes will take effect on next run")
121 );
122
123 Ok(())
124 }
125}
126
127impl Command for ConfigCommand {
128 fn execute(&self) -> CliResult<()> {
129 match &self.action {
130 ConfigAction::List => self.list_config(),
131 ConfigAction::Get(key) => self.get_config(key),
132 ConfigAction::Set(key, value) => self.set_config(key, value),
133 }
134 }
135}