From 3da214ae4c14f57dc5f6ecd480330936f00e1a4f Mon Sep 17 00:00:00 2001 From: Lucien Cartier-Tilet Date: Sun, 5 Apr 2026 16:38:03 +0200 Subject: [PATCH] refactor(prompter): simplify commit type selection --- src/prompts/prompter.rs | 64 +++++++---------------------------------- 1 file changed, 10 insertions(+), 54 deletions(-) diff --git a/src/prompts/prompter.rs b/src/prompts/prompter.rs index 1367424..44b2e43 100644 --- a/src/prompts/prompter.rs +++ b/src/prompts/prompter.rs @@ -66,67 +66,32 @@ pub struct RealPrompts; impl Prompter for RealPrompts { fn select_commit_type(&self) -> Result { - use inquire::Select; - - let options: Vec<_> = CommitType::all() - .iter() - .map(|ct| format!("{}: {}", ct, ct.description())) - .collect(); - - let answer = Select::new("Select commit type:", options) + inquire::Select::new("Select commit type:", CommitType::all().to_vec()) .with_page_size(11) .with_help_message( "Use arrow keys to navigate, Enter to select. See https://www.conventionalcommits.org/ for details.", ) + .with_formatter(&|option| format!("{}: {}", option.value.as_str(), option.value.description())) .prompt() - .map_err(|_| Error::Cancelled)?; - - // Extract the commit type from the selected option - let selected_type = answer - .split(':') - .next() - .ok_or_else(|| Error::JjOperation { - context: "Failed to parse selected commit type".to_string(), - })? - .trim(); - - CommitType::all() - .iter() - .find(|ct| ct.as_str() == selected_type) - .copied() - .ok_or_else(|| Error::JjOperation { - context: format!("Unknown commit type: {}", selected_type), - }) + .map_err(|_| Error::Cancelled) } fn input_scope(&self) -> Result { - use inquire::Text; - - let answer = Text::new("Enter scope (optional):") + let answer = inquire::Text::new("Enter scope (optional):") .with_help_message( "Scope is optional. If provided, it should be a noun representing the section of code affected (e.g., 'api', 'ui', 'config'). Max 30 characters.", ) .with_placeholder("Leave empty if no scope") .prompt_skippable() .map_err(|_| Error::Cancelled)?; - - // Empty input is valid (no scope) - let answer_str = match answer { - Some(s) => s, - None => return Ok(Scope::empty()), - }; - - if answer_str.trim().is_empty() { - return Ok(Scope::empty()); + match answer { + Some(s) if s.trim().is_empty() => Ok(Scope::empty()), + Some(s) => Scope::parse(s.trim()).map_err(|e| Error::InvalidScope(e.to_string())), + None => Ok(Scope::empty()), } - - // Parse and validate the scope - Scope::parse(answer_str.trim()).map_err(|e| Error::InvalidScope(e.to_string())) } fn input_description(&self) -> Result { - use inquire::Text; - loop { let answer = Text::new("Enter description (required):") .with_help_message( @@ -180,13 +145,10 @@ impl Prompter for RealPrompts { } fn input_body(&self) -> Result { - use inquire::Editor; - let wants_body = Confirm::new("Add a body?") .with_default(false) .prompt() .map_err(|_| Error::Cancelled)?; - if !wants_body { return Ok(Body::default()); } @@ -196,12 +158,11 @@ JJ: Body (optional). Markdown is supported.\n\ JJ: Wrap prose lines at 72 characters where possible.\n\ JJ: Lines starting with \"JJ:\" will be removed.\n"; - let raw = Editor::new("Body:") + let raw = inquire::Editor::new("Body:") .with_predefined_text(template) .with_file_extension(".md") .prompt() .map_err(|_| Error::Cancelled)?; - let stripped: String = raw .lines() .filter(|line| !line.starts_with("JJ:")) @@ -212,16 +173,11 @@ JJ: Lines starting with \"JJ:\" will be removed.\n"; } fn confirm_apply(&self, message: &str) -> Result { - use inquire::Confirm; - - // Show preview println!( "\nšŸ“ Commit Message Preview:\n{}\n", format_message_box(message) ); - - // Get confirmation - Confirm::new("Apply this commit message?") + inquire::Confirm::new("Apply this commit message?") .with_default(true) .with_help_message("Select 'No' to cancel and start over") .prompt()