diff options
Diffstat (limited to 'src/lib/cli_interactor.rs')
| -rw-r--r-- | src/lib/cli_interactor.rs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/lib/cli_interactor.rs b/src/lib/cli_interactor.rs index 8fca81d..8bcda19 100644 --- a/src/lib/cli_interactor.rs +++ b/src/lib/cli_interactor.rs | |||
| @@ -236,6 +236,93 @@ impl PromptMultiChoiceParms { | |||
| 236 | } | 236 | } |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | pub fn multi_select_with_custom_value<F>( | ||
| 240 | prompt: &str, | ||
| 241 | custom_choice_prompt: &str, | ||
| 242 | mut choices: Vec<String>, | ||
| 243 | mut defaults: Vec<bool>, | ||
| 244 | validate_choice: F, | ||
| 245 | ) -> Result<Vec<String>> | ||
| 246 | where | ||
| 247 | F: Fn(&str) -> Result<String>, | ||
| 248 | { | ||
| 249 | let mut selected_choices = vec![]; | ||
| 250 | |||
| 251 | // Loop to allow users to add more choices | ||
| 252 | loop { | ||
| 253 | // Add 'add another' option at the end of the choices | ||
| 254 | let mut current_choices = choices.clone(); | ||
| 255 | current_choices.push(if current_choices.is_empty() { | ||
| 256 | "add".to_string() | ||
| 257 | } else { | ||
| 258 | "add another".to_string() | ||
| 259 | }); | ||
| 260 | |||
| 261 | // Create default selections based on the provided defaults | ||
| 262 | let mut current_defaults = defaults.clone(); | ||
| 263 | current_defaults.push(current_choices.len() == 1); // 'add another' should not be selected by default | ||
| 264 | |||
| 265 | // Prompt for selections | ||
| 266 | let selected_indices: Vec<usize> = Interactor::default().multi_choice( | ||
| 267 | PromptMultiChoiceParms::default() | ||
| 268 | .with_prompt(prompt) | ||
| 269 | .dont_report() | ||
| 270 | .with_choices(current_choices.clone()) | ||
| 271 | .with_defaults(current_defaults), | ||
| 272 | )?; | ||
| 273 | |||
| 274 | // Collect selected choices | ||
| 275 | selected_choices.clear(); // Clear previous selections to update | ||
| 276 | for &index in &selected_indices { | ||
| 277 | if index < choices.len() { | ||
| 278 | // Exclude 'add another' option | ||
| 279 | selected_choices.push(choices[index].clone()); | ||
| 280 | } | ||
| 281 | } | ||
| 282 | |||
| 283 | // Check if 'add another' was selected | ||
| 284 | if selected_indices.contains(&(choices.len())) { | ||
| 285 | // Last index is 'add another' | ||
| 286 | let mut new_choice: String; | ||
| 287 | loop { | ||
| 288 | new_choice = Interactor::default().input( | ||
| 289 | PromptInputParms::default() | ||
| 290 | .with_prompt(custom_choice_prompt) | ||
| 291 | .dont_report() | ||
| 292 | .optional(), | ||
| 293 | )?; | ||
| 294 | |||
| 295 | if new_choice.is_empty() { | ||
| 296 | break; | ||
| 297 | } | ||
| 298 | // Validate the new choice | ||
| 299 | match validate_choice(&new_choice) { | ||
| 300 | Ok(valid_choice) => { | ||
| 301 | new_choice = valid_choice; // Use the fixed version of the input | ||
| 302 | break; // Valid choice, exit the loop | ||
| 303 | } | ||
| 304 | Err(err) => { | ||
| 305 | // Inform the user about the validation error | ||
| 306 | println!("Error: {err}"); | ||
| 307 | } | ||
| 308 | } | ||
| 309 | } | ||
| 310 | |||
| 311 | // Add the new choice to the choices vector | ||
| 312 | if !new_choice.is_empty() { | ||
| 313 | choices.push(new_choice.clone()); // Add new choice to the end of the list | ||
| 314 | selected_choices.push(new_choice); // Automatically select the new choice | ||
| 315 | defaults.push(true); // Set the new choice as selected by default | ||
| 316 | } | ||
| 317 | } else { | ||
| 318 | // Exit the loop if 'add another' was not selected | ||
| 319 | break; | ||
| 320 | } | ||
| 321 | } | ||
| 322 | |||
| 323 | Ok(selected_choices) | ||
| 324 | } | ||
| 325 | |||
| 239 | #[derive(Debug, Default)] | 326 | #[derive(Debug, Default)] |
| 240 | pub struct Printer { | 327 | pub struct Printer { |
| 241 | printed_lines: Vec<String>, | 328 | printed_lines: Vec<String>, |