claude_code_switcher/
confirm_selector.rs

1//! Enhanced confirmation selector with keyboard shortcuts and better UX
2
3use anyhow::{Result, anyhow};
4use console::style;
5use inquire::{Confirm, Select};
6
7/// Enhanced confirmation selector that supports y/n shortcuts, arrow keys, and q exit
8pub struct ConfirmSelector {
9    message: String,
10    default: bool,
11}
12
13impl ConfirmSelector {
14    pub fn new(message: &str, default: bool) -> Self {
15        Self {
16            message: message.to_string(),
17            default,
18        }
19    }
20
21    /// Run the enhanced confirmation selector
22    pub fn run(&self) -> Result<bool> {
23        // If not in interactive mode, return default
24        if !atty::is(atty::Stream::Stdin) {
25            return Ok(self.default);
26        }
27
28        // First try the enhanced selector
29        if let Ok(result) = self.run_enhanced_selector() {
30            return Ok(result);
31        }
32
33        // Fallback to standard confirm
34        Confirm::new(&self.message)
35            .with_default(self.default)
36            .with_help_message("Press Y for Yes, N for No, or Q to Quit")
37            .prompt()
38            .map_err(|e| anyhow!("Failed to get confirmation: {}", e))
39    }
40
41    fn run_enhanced_selector(&self) -> Result<bool> {
42        // Create enhanced options with keyboard shortcuts
43        let options = vec![
44            format!("✓ Yes {}", style("(Y)").green()),
45            format!("✗ No {}", style("(N)").red()),
46            format!("⚠ Quit {}", style("(Q)").yellow()),
47        ];
48
49        let prompt = self.message.clone();
50
51        match Select::new(&prompt, options).prompt() {
52            Ok(choice) => {
53                match choice.as_str() {
54                    choice if choice.contains("Yes") => Ok(true),
55                    choice if choice.contains("No") => Ok(false),
56                    choice if choice.contains("Quit") => {
57                        println!("{}", style("🚫 Operation cancelled by user.").yellow());
58                        std::process::exit(0);
59                    }
60                    _ => Ok(self.default), // Should not happen, but provide fallback
61                }
62            }
63            Err(e) => Err(anyhow!("Enhanced selector failed: {}", e)),
64        }
65    }
66}
67
68/// Quick confirmation function with enhanced selector
69pub fn confirm_with_enhanced_selector(message: &str, default: bool) -> Result<bool> {
70    let selector = ConfirmSelector::new(message, default);
71    selector.run()
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn test_confirm_selector_creation() {
80        let selector = ConfirmSelector::new("Test message", true);
81        assert_eq!(selector.message, "Test message");
82        assert_eq!(selector.default, true);
83    }
84}