upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/lib/cli_interactor.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/cli_interactor.rs')
-rw-r--r--src/lib/cli_interactor.rs87
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
239pub 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>>
246where
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)]
240pub struct Printer { 327pub struct Printer {
241 printed_lines: Vec<String>, 328 printed_lines: Vec<String>,