Skip to main content

rskit_cli/prompt/
key.rs

1//! The keystroke vocabulary a key-driven [`Terminal`](crate::prompt::terminal::Terminal) yields.
2//!
3//! [`Key`] is rskit's own, minimal key abstraction so no third-party terminal
4//! type (crossterm, termion, …) leaks into the public prompt surface. The rich
5//! terminal maps platform events onto it; the scripted terminal feeds canned
6//! sequences of it in tests.
7
8/// A single decoded keystroke from an interactive terminal.
9///
10/// Only the keys the prompt widgets act on are modelled; anything else decodes
11/// to [`Key::Unknown`] so callers can ignore it without a catch-all on a
12/// platform enum.
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14#[non_exhaustive]
15pub enum Key {
16    /// Confirm the current answer (Enter / Return).
17    Enter,
18    /// Space bar — toggles the focused item in multi-select, or inserts a
19    /// literal space in text entry.
20    Space,
21    /// Delete the character before the cursor (Backspace).
22    Backspace,
23    /// Abandon the prompt (Escape).
24    Escape,
25    /// Advance focus (Tab).
26    Tab,
27    /// Move focus up / to the previous item.
28    Up,
29    /// Move focus down / to the next item.
30    Down,
31    /// Move the text cursor left.
32    Left,
33    /// Move the text cursor right.
34    Right,
35    /// Jump to the first item / start of line.
36    Home,
37    /// Jump to the last item / end of line.
38    End,
39    /// A printable character was typed.
40    Char(char),
41    /// A cancellation request (Ctrl+C / Ctrl+D).
42    Interrupt,
43    /// A key with no prompt-relevant meaning.
44    Unknown,
45}
46
47impl Key {
48    /// Whether this key represents a cancellation request.
49    #[must_use]
50    pub const fn is_interrupt(self) -> bool {
51        matches!(self, Self::Interrupt)
52    }
53}
54
55#[cfg(test)]
56mod tests {
57    use super::Key;
58
59    #[test]
60    fn only_interrupt_reports_as_interrupt() {
61        assert!(Key::Interrupt.is_interrupt());
62        for key in [
63            Key::Enter,
64            Key::Escape,
65            Key::Char('a'),
66            Key::Space,
67            Key::Unknown,
68        ] {
69            assert!(!key.is_interrupt());
70        }
71    }
72}