xacli_components/components/confirm/
mod.rs1use std::io::Write;
2
3use crossterm::{
4 cursor,
5 event::{Event, KeyCode, KeyModifiers},
6 queue, style, terminal,
7};
8use xacli_core::{ComponentInfo, Context, Error, InputComponent, InputValue, Result};
9
10pub struct Confirm {
11 prompt: String,
12 default: bool,
13}
14
15impl Confirm {
16 pub fn new(prompt: impl Into<String>) -> Self {
17 Self {
18 prompt: prompt.into(),
19 default: false,
20 }
21 }
22
23 fn render(&self, ctx: &mut dyn Context, choice: bool) -> Result<()> {
24 let hint = if choice { "(Y/n)" } else { "(y/N)" };
25
26 let mut stdout = ctx.stdout();
27
28 queue!(
29 stdout,
30 cursor::MoveToColumn(0),
31 terminal::Clear(terminal::ClearType::CurrentLine),
32 style::Print(&self.prompt),
33 style::Print(" "),
34 style::Print(hint),
35 )?;
36
37 stdout.flush()?;
38 Ok(())
39 }
40
41 fn run_inner(&mut self, ctx: &mut dyn Context) -> Result<InputValue> {
42 let mut choice = self.default;
43
44 self.render(ctx, choice)?;
45
46 loop {
47 if let Event::Key(key) = ctx.read_event()? {
48 match key.code {
49 KeyCode::Enter => {
50 return Ok(InputValue::Bool(choice));
51 }
52 KeyCode::Esc => {
53 return Err(Error::InterruptError);
54 }
55 KeyCode::Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => {
56 return Err(Error::InterruptError);
57 }
58 KeyCode::Char('y') | KeyCode::Char('Y') => {
59 choice = true;
60 self.render(ctx, choice)?;
61 }
62 KeyCode::Char('n') | KeyCode::Char('N') => {
63 choice = false;
64 self.render(ctx, choice)?;
65 }
66 KeyCode::Left | KeyCode::Right => {
67 choice = !choice;
68 self.render(ctx, choice)?;
69 }
70 _ => {}
71 }
72 }
73 }
74 }
75}
76
77impl InputComponent for Confirm {
78 fn info(&self) -> ComponentInfo {
79 ComponentInfo {
80 name: "confirm".to_string(),
81 title: "Confirmation Prompt".to_string(),
82 description: self.prompt.clone(),
83 }
84 }
85
86 fn run(&mut self, ctx: &mut dyn Context) -> Result<InputValue> {
87 terminal::enable_raw_mode()?;
89 let result = self.run_inner(ctx);
90 let _ = terminal::disable_raw_mode();
92 result
93 }
94}