Skip to main content

holodeck_simctl_tui/state/
key.rs

1/// Reducer-facing key abstraction, independent of the terminal backend.
2/// Phase 5 maps crossterm's `KeyEvent` onto this; keeping the reducer
3/// decoupled from crossterm is what lets these tests run without a terminal.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum Key {
6    Up,
7    Down,
8    Left,
9    Right,
10    Enter,
11    Escape,
12    Tab,
13    Backspace,
14    Char(char),
15    Unknown,
16}
17
18/// Accepts anything visually representable on one line: rejects newlines/line
19/// separators and C0/DEL control characters; admits letters, digits,
20/// punctuation, symbols, and other whitespace.
21pub fn is_printable(c: char) -> bool {
22    if matches!(c, '\n' | '\r' | '\u{0B}' | '\u{0C}' | '\u{85}' | '\u{2028}' | '\u{2029}') {
23        return false;
24    }
25    (c as u32) >= 0x20 && (c as u32) != 0x7F
26}
27
28#[cfg(test)]
29mod tests {
30    use super::*;
31
32    #[test]
33    fn rejects_newlines_and_control_characters() {
34        assert!(!is_printable('\n'));
35        assert!(!is_printable('\r'));
36        assert!(!is_printable('\u{7F}'));
37        assert!(!is_printable('\u{1B}'));
38    }
39
40    #[test]
41    fn accepts_letters_digits_punctuation_and_space() {
42        for c in ['a', 'Z', '0', '!', ' ', 'é', '—'] {
43            assert!(is_printable(c), "{c:?} should be printable");
44        }
45    }
46}