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:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-08-07 17:52:22 +0100
committerDanConwayDev <DanConwayDev@protonmail.com>2025-08-07 17:52:22 +0100
commit92c2362a9bed1bc1f256e7948e087c4102b7c4f9 (patch)
tree700bf840ba52a8bd576afcfbe532a669f104dfcb /src/lib/cli_interactor.rs
parent8724af191f520a822214109f75a1851856c74fd2 (diff)
parentfa7adf840ac2d78defee398a61b60888f615622a (diff)
Merge branch 'add-prs-to-ngit-send'
Diffstat (limited to 'src/lib/cli_interactor.rs')
-rw-r--r--src/lib/cli_interactor.rs105
1 files changed, 104 insertions, 1 deletions
diff --git a/src/lib/cli_interactor.rs b/src/lib/cli_interactor.rs
index 8fca81d..e944bf9 100644
--- a/src/lib/cli_interactor.rs
+++ b/src/lib/cli_interactor.rs
@@ -1,5 +1,8 @@
1use anyhow::{Context, Result}; 1use anyhow::{Context, Result};
2use dialoguer::{Confirm, Input, Password, theme::ColorfulTheme}; 2use dialoguer::{
3 Confirm, Input, Password,
4 theme::{ColorfulTheme, Theme},
5};
3use indicatif::TermLike; 6use indicatif::TermLike;
4#[cfg(test)] 7#[cfg(test)]
5use mockall::*; 8use mockall::*;
@@ -236,6 +239,106 @@ impl PromptMultiChoiceParms {
236 } 239 }
237} 240}
238 241
242pub fn multi_select_with_custom_value<F>(
243 prompt: &str,
244 custom_choice_prompt: &str,
245 mut choices: Vec<String>,
246 mut defaults: Vec<bool>,
247 validate_choice: F,
248) -> Result<Vec<String>>
249where
250 F: Fn(&str) -> Result<String>,
251{
252 let mut selected_choices = vec![];
253
254 // Loop to allow users to add more choices
255 loop {
256 // Add 'add another' option at the end of the choices
257 let mut current_choices = choices.clone();
258 current_choices.push(if current_choices.is_empty() {
259 "add".to_string()
260 } else {
261 "add another".to_string()
262 });
263
264 // Create default selections based on the provided defaults
265 let mut current_defaults = defaults.clone();
266 current_defaults.push(current_choices.len() == 1); // 'add another' should not be selected by default
267
268 // Prompt for selections
269 let selected_indices: Vec<usize> = Interactor::default().multi_choice(
270 PromptMultiChoiceParms::default()
271 .with_prompt(prompt)
272 .dont_report()
273 .with_choices(current_choices.clone())
274 .with_defaults(current_defaults),
275 )?;
276
277 // Collect selected choices
278 selected_choices.clear(); // Clear previous selections to update
279 for &index in &selected_indices {
280 if index < choices.len() {
281 // Exclude 'add another' option
282 selected_choices.push(choices[index].clone());
283 }
284 }
285
286 // Check if 'add another' was selected
287 if selected_indices.contains(&(choices.len())) {
288 // Last index is 'add another'
289 let mut new_choice: String;
290 loop {
291 new_choice = Interactor::default().input(
292 PromptInputParms::default()
293 .with_prompt(custom_choice_prompt)
294 .dont_report()
295 .optional(),
296 )?;
297
298 if new_choice.is_empty() {
299 break;
300 }
301 // Validate the new choice
302 match validate_choice(&new_choice) {
303 Ok(valid_choice) => {
304 new_choice = valid_choice; // Use the fixed version of the input
305 break; // Valid choice, exit the loop
306 }
307 Err(err) => {
308 // Inform the user about the validation error
309 println!("Error: {err}");
310 }
311 }
312 }
313
314 // Add the new choice to the choices vector
315 if !new_choice.is_empty() {
316 choices.push(new_choice.clone()); // Add new choice to the end of the list
317 selected_choices.push(new_choice); // Automatically select the new choice
318 defaults.push(true); // Set the new choice as selected by default
319 }
320 } else {
321 // Exit the loop if 'add another' was not selected
322 break;
323 }
324 }
325
326 Ok(selected_choices)
327}
328
329pub fn show_multi_input_prompt_success(label: &str, values: &[String]) {
330 let values_str: Vec<&str> = values.iter().map(std::string::String::as_str).collect();
331 eprintln!("{}", {
332 let mut s = String::new();
333 let _ = ColorfulTheme::default().format_multi_select_prompt_selection(
334 &mut s,
335 label,
336 &values_str,
337 );
338 s
339 });
340}
341
239#[derive(Debug, Default)] 342#[derive(Debug, Default)]
240pub struct Printer { 343pub struct Printer {
241 printed_lines: Vec<String>, 344 printed_lines: Vec<String>,