cc_switch/config/
config.rs1use anyhow::{Context, Result};
2use std::collections::BTreeMap;
3use std::path::PathBuf;
4
5use crate::config::types::Configuration;
6
7type EnvVarMap = BTreeMap<String, String>;
9type EnvVarTuple = (String, String);
11type EnvVarTuples = Vec<EnvVarTuple>;
13
14#[derive(Default, Clone)]
18pub struct EnvironmentConfig {
19 pub env_vars: EnvVarMap,
21}
22
23impl EnvironmentConfig {
24 pub fn from_config(config: &Configuration) -> Self {
32 let mut env_vars = EnvVarMap::new();
33
34 env_vars.insert("ANTHROPIC_AUTH_TOKEN".to_string(), config.token.clone());
36 env_vars.insert("ANTHROPIC_BASE_URL".to_string(), config.url.clone());
37
38 if let Some(model) = &config.model
40 && !model.is_empty()
41 {
42 env_vars.insert("ANTHROPIC_MODEL".to_string(), model.clone());
43 }
44
45 if let Some(small_fast_model) = &config.small_fast_model
46 && !small_fast_model.is_empty()
47 {
48 env_vars.insert(
49 "ANTHROPIC_SMALL_FAST_MODEL".to_string(),
50 small_fast_model.clone(),
51 );
52 }
53
54 if let Some(max_thinking_tokens) = config.max_thinking_tokens {
56 env_vars.insert(
57 "ANTHROPIC_MAX_THINKING_TOKENS".to_string(),
58 max_thinking_tokens.to_string(),
59 );
60 }
61
62 if let Some(timeout) = config.api_timeout_ms {
64 env_vars.insert("API_TIMEOUT_MS".to_string(), timeout.to_string());
65 }
66
67 if let Some(flag) = config.claude_code_disable_nonessential_traffic {
69 env_vars.insert(
70 "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC".to_string(),
71 flag.to_string(),
72 );
73 }
74
75 if let Some(model) = &config.anthropic_default_sonnet_model
77 && !model.is_empty()
78 {
79 env_vars.insert("ANTHROPIC_DEFAULT_SONNET_MODEL".to_string(), model.clone());
80 }
81
82 if let Some(model) = &config.anthropic_default_opus_model
84 && !model.is_empty()
85 {
86 env_vars.insert("ANTHROPIC_DEFAULT_OPUS_MODEL".to_string(), model.clone());
87 }
88
89 if let Some(model) = &config.anthropic_default_haiku_model
91 && !model.is_empty()
92 {
93 env_vars.insert("ANTHROPIC_DEFAULT_HAIKU_MODEL".to_string(), model.clone());
94 }
95
96 EnvironmentConfig { env_vars }
97 }
98
99 pub fn empty() -> Self {
101 EnvironmentConfig {
102 env_vars: EnvVarMap::new(),
103 }
104 }
105
106 pub fn as_env_tuples(&self) -> EnvVarTuples {
109 self.env_vars
110 .iter()
111 .map(|(k, v)| (k.clone(), v.clone()))
112 .collect()
113 }
114}
115
116pub fn get_config_storage_path() -> Result<PathBuf> {
123 let home_dir = dirs::home_dir().context("Could not find home directory")?;
124 Ok(home_dir.join(".claude").join("cc_auto_switch_setting.json"))
125}
126
127pub fn validate_alias_name(alias_name: &str) -> Result<()> {
135 if alias_name.is_empty() {
136 anyhow::bail!("Alias name cannot be empty");
137 }
138 if alias_name == "cc" {
139 anyhow::bail!("Alias name 'cc' is reserved and cannot be used");
140 }
141 if alias_name.chars().any(|c| c.is_whitespace()) {
142 anyhow::bail!("Alias name cannot contain whitespace");
143 }
144 Ok(())
145}