#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Key {
Up,
Down,
Left,
Right,
Enter,
Escape,
Backspace,
Delete,
Home,
End,
Character(char),
}
impl Key {
#[must_use]
pub fn label(self) -> String {
match self {
Self::Up => "↑".to_owned(),
Self::Down => "↓".to_owned(),
Self::Left => "←".to_owned(),
Self::Right => "→".to_owned(),
Self::Enter => "Enter".to_owned(),
Self::Escape => "Esc".to_owned(),
Self::Backspace => "Backspace".to_owned(),
Self::Delete => "Del".to_owned(),
Self::Home => "Home".to_owned(),
Self::End => "End".to_owned(),
Self::Character(' ') => "Space".to_owned(),
Self::Character(character) => character.to_string(),
}
}
#[must_use]
pub const fn typed(self) -> Option<char> {
match self {
Self::Character(character) => Some(character),
Self::Up
| Self::Down
| Self::Left
| Self::Right
| Self::Enter
| Self::Escape
| Self::Backspace
| Self::Delete
| Self::Home
| Self::End => None,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Keystroke {
pub key: Key,
pub control: bool,
pub alternate: bool,
}
impl Keystroke {
#[must_use]
pub const fn plain(key: Key) -> Self {
Self {
key,
control: false,
alternate: false,
}
}
#[must_use]
pub const fn control(key: Key) -> Self {
Self {
key,
control: true,
alternate: false,
}
}
#[must_use]
pub const fn modified(self) -> bool {
self.control || self.alternate
}
#[must_use]
pub fn label(self) -> String {
let key = if self.modified() {
self.key.label().to_uppercase()
} else {
self.key.label()
};
match (self.control, self.alternate) {
(false, false) => key,
(true, false) => format!("Ctrl+{key}"),
(false, true) => format!("Alt+{key}"),
(true, true) => format!("Ctrl+Alt+{key}"),
}
}
}
pub const EXIT_KEYSTROKE: Keystroke = Keystroke::control(Key::Character('q'));