1+ use colored:: * ;
2+ use question:: { Answer , Question } ;
13use serde:: { Deserialize , Serialize } ;
24use std:: collections:: HashMap ;
3- use std:: path:: PathBuf ;
45use std:: fs;
5- use question:: { Question , Answer } ;
6- use colored:: * ;
6+ use std:: path:: PathBuf ;
77
88#[ derive( Serialize , Deserialize , Debug , Default ) ]
99pub struct Config {
@@ -50,15 +50,17 @@ pub fn load_config() -> Result<Config, String> {
5050 let config_path = get_config_path ( ) ?. join ( "config.toml" ) ;
5151 if !config_path. exists ( ) {
5252 println ! ( "{}" , "Configuration file not found." . yellow( ) ) ;
53- println ! ( "Please run '{}' to get started." , "commitcraft setup" . bold( ) . cyan( ) ) ;
53+ println ! (
54+ "Please run '{}' to get started." ,
55+ "commitcraft setup" . bold( ) . cyan( )
56+ ) ;
5457 return Err ( "Config not found" . to_string ( ) ) ;
5558 }
5659
5760 let content = fs:: read_to_string ( & config_path)
5861 . map_err ( |e| format ! ( "Failed to read config file: {}" , e) ) ?;
5962
60- toml:: from_str ( & content)
61- . map_err ( |e| format ! ( "Failed to parse config file: {}" , e) )
63+ toml:: from_str ( & content) . map_err ( |e| format ! ( "Failed to parse config file: {}" , e) )
6264}
6365
6466pub fn run_setup ( ) -> Result < ( ) , String > {
@@ -68,30 +70,36 @@ pub fn run_setup() -> Result<(), String> {
6870 let mut config = load_config ( ) . unwrap_or_default ( ) ;
6971
7072 // Ask for default provider
71- let provider_answer = Question :: new ( "Which AI provider do you want to use by default? (gemini, openai, anthropic)" )
72- . ask ( ) . ok_or ( "Failed to ask question" . to_string ( ) ) ?;
73+ let provider_answer = Question :: new (
74+ "Which AI provider do you want to use by default? (gemini, openai, anthropic)" ,
75+ )
76+ . ask ( )
77+ . ok_or ( "Failed to ask question" . to_string ( ) ) ?;
7378 let provider_choice = match provider_answer {
7479 Answer :: RESPONSE ( s) => s,
7580 _ => return Err ( "Invalid answer type for provider choice" . to_string ( ) ) ,
76- } . to_lowercase ( ) ;
77-
81+ }
82+ . to_lowercase ( ) ;
83+
7884 config. default_provider = Some ( provider_choice. clone ( ) ) ;
7985
8086 println ! ( "\n Now, let's add API keys. You can leave any of them blank." ) ;
81-
87+
8288 // Ask for API keys
8389 let openai_key_answer = Question :: new ( "Enter your OpenAI API key (starts with 'sk-'):" )
84- . ask ( ) . ok_or ( "Failed to ask question" . to_string ( ) ) ?;
90+ . ask ( )
91+ . ok_or ( "Failed to ask question" . to_string ( ) ) ?;
8592 let openai_key = match openai_key_answer {
8693 Answer :: RESPONSE ( s) => s,
8794 _ => String :: new ( ) , // Default to empty if not a string response, or handle error
8895 } ;
8996 if !openai_key. is_empty ( ) {
9097 config. api_keys . openai = Some ( openai_key) ;
9198 }
92-
99+
93100 let gemini_key_answer = Question :: new ( "Enter your Google AI (Gemini) API key:" )
94- . ask ( ) . ok_or ( "Failed to ask question" . to_string ( ) ) ?;
101+ . ask ( )
102+ . ok_or ( "Failed to ask question" . to_string ( ) ) ?;
95103 let gemini_key = match gemini_key_answer {
96104 Answer :: RESPONSE ( s) => s,
97105 _ => String :: new ( ) ,
@@ -101,7 +109,8 @@ pub fn run_setup() -> Result<(), String> {
101109 }
102110
103111 let anthropic_key_answer = Question :: new ( "Enter your Anthropic (Claude) API key:" )
104- . ask ( ) . ok_or ( "Failed to ask question" . to_string ( ) ) ?;
112+ . ask ( )
113+ . ok_or ( "Failed to ask question" . to_string ( ) ) ?;
105114 let anthropic_key = match anthropic_key_answer {
106115 Answer :: RESPONSE ( s) => s,
107116 _ => String :: new ( ) ,
@@ -111,50 +120,64 @@ pub fn run_setup() -> Result<(), String> {
111120 }
112121
113122 // Setup aliases
114- let setup_aliases = Question :: new ( "Do you want to set up model aliases? (e.g., 'fast' -> 'gemini-1.5-flash-latest')" )
115- . yes_no ( )
116- . default ( Answer :: YES )
117- . ask ( ) . ok_or ( "Failed to ask question" . to_string ( ) ) ?;
123+ let setup_aliases = Question :: new (
124+ "Do you want to set up model aliases? (e.g., 'fast' -> 'gemini-1.5-flash-latest')" ,
125+ )
126+ . yes_no ( )
127+ . default ( Answer :: YES )
128+ . ask ( )
129+ . ok_or ( "Failed to ask question" . to_string ( ) ) ?;
118130
119131 if let Answer :: YES = setup_aliases {
120- config. aliases . insert ( "fast" . to_string ( ) , "gemini-1.5-flash-latest" . to_string ( ) ) ;
121- config. aliases . insert ( "smart" . to_string ( ) , "gpt-4o" . to_string ( ) ) ;
132+ config
133+ . aliases
134+ . insert ( "fast" . to_string ( ) , "gemini-1.5-flash-latest" . to_string ( ) ) ;
135+ config
136+ . aliases
137+ . insert ( "smart" . to_string ( ) , "gpt-4o" . to_string ( ) ) ;
122138 println ! ( "Default aliases 'fast' and 'smart' have been added." ) ;
123139 }
124-
140+
125141 save_config ( & config) ?;
126-
127- println ! ( "\n {}" , "Setup complete! Your configuration has been saved." . bold( ) . green( ) ) ;
142+
143+ println ! (
144+ "\n {}" ,
145+ "Setup complete! Your configuration has been saved."
146+ . bold( )
147+ . green( )
148+ ) ;
128149 Ok ( ( ) )
129150}
130151
131152fn save_config ( config : & Config ) -> Result < ( ) , String > {
132153 let config_path = get_config_path ( ) ?. join ( "config.toml" ) ;
133154 let config_dir = config_path. parent ( ) . unwrap ( ) ;
134-
155+
135156 fs:: create_dir_all ( config_dir)
136157 . map_err ( |e| format ! ( "Failed to create config directory: {}" , e) ) ?;
137158
138- let toml_string = toml:: to_string_pretty ( config)
139- . map_err ( |e| format ! ( "Failed to serialize config: {}" , e) ) ?;
140-
141- fs:: write ( & config_path, toml_string)
142- . map_err ( |e| format ! ( "Failed to write config file: {}" , e) )
159+ let toml_string =
160+ toml:: to_string_pretty ( config) . map_err ( |e| format ! ( "Failed to serialize config: {}" , e) ) ?;
161+
162+ fs:: write ( & config_path, toml_string) . map_err ( |e| format ! ( "Failed to write config file: {}" , e) )
143163}
144164
145165#[ cfg( test) ]
146166mod tests {
147167 use super :: * ;
168+ use std:: collections:: HashMap ;
148169 use std:: fs;
149170 use std:: path:: PathBuf ;
150- use std:: collections:: HashMap ;
151171
152172 #[ test]
153173 fn test_models_default ( ) {
154174 let models = Models :: default ( ) ;
155175 assert_eq ! ( models. openai, Some ( "gpt-4o-mini" . to_string( ) ) ) ;
156176 assert_eq ! ( models. gemini, Some ( "gemini-1.5-flash-latest" . to_string( ) ) ) ;
157- assert_eq ! ( models. anthropic, Some ( "claude-3-haiku-20240307" . to_string( ) ) ) ;
177+ assert_eq ! (
178+ models. anthropic,
179+ Some ( "claude-3-haiku-20240307" . to_string( ) )
180+ ) ;
158181 }
159182
160183 #[ test]
@@ -176,13 +199,18 @@ mod tests {
176199 config. default_provider = Some ( "openai" . to_string ( ) ) ;
177200 config. api_keys . openai = Some ( "sk-test" . to_string ( ) ) ;
178201 config. models . openai = Some ( "gpt-4" . to_string ( ) ) ;
179- config. aliases . insert ( "fast" . to_string ( ) , "gpt-4o-mini" . to_string ( ) ) ;
202+ config
203+ . aliases
204+ . insert ( "fast" . to_string ( ) , "gpt-4o-mini" . to_string ( ) ) ;
180205 let toml = toml:: to_string ( & config) . unwrap ( ) ;
181206 let deserialized: Config = toml:: from_str ( & toml) . unwrap ( ) ;
182207 assert_eq ! ( deserialized. default_provider, Some ( "openai" . to_string( ) ) ) ;
183208 assert_eq ! ( deserialized. api_keys. openai, Some ( "sk-test" . to_string( ) ) ) ;
184209 assert_eq ! ( deserialized. models. openai, Some ( "gpt-4" . to_string( ) ) ) ;
185- assert_eq ! ( deserialized. aliases. get( "fast" ) , Some ( & "gpt-4o-mini" . to_string( ) ) ) ;
210+ assert_eq ! (
211+ deserialized. aliases. get( "fast" ) ,
212+ Some ( & "gpt-4o-mini" . to_string( ) )
213+ ) ;
186214 }
187215
188216 #[ test]
0 commit comments