diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2025-08-06 12:52:59 +0100 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2025-08-07 17:25:50 +0100 |
| commit | a9b2ebf8216be34950e54dd9a446dbdc0c9c744a (patch) | |
| tree | 5a103933852fbcfcd42b13716cb92eeca5325d6d /src/lib/cli_interactor.rs | |
| parent | 29f61ffdf155ea88b8d9aec23d28cf70baba577e (diff) | |
feat(send): PR fallback to user / custom grasp
if use is maintainer, push PR to all repo git servers.
if user has a fork, push to all git servers it lists, and repo
grasp servers.
if user hasn't got a fork but has a user grasp list and pushing
push to repo grasp servers fails, create a personal-fork
automatically at each user grasp server and push there.
fallback to prompting user for either grasp servers or git server
with write permission.
if user provides grasp servers, suggesting adding to user preference
list.
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>, |