use crossterm::event::{KeyCode, KeyModifiers as CrosstermModifiers};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Key {
Char(char),
F(u8),
Backspace,
Enter,
Left,
Right,
Up,
Down,
Home,
End,
PageUp,
PageDown,
Tab,
BackTab,
Delete,
Insert,
Esc,
CapsLock,
ScrollLock,
NumLock,
PrintScreen,
Pause,
Menu,
Null,
}
impl Key {
#[must_use]
pub const fn is_esc(&self) -> bool {
matches!(self, Key::Esc)
}
#[must_use]
pub const fn is_enter(&self) -> bool {
matches!(self, Key::Enter)
}
#[must_use]
pub const fn is_char(&self) -> bool {
matches!(self, Key::Char(_))
}
#[must_use]
pub const fn char(&self) -> Option<char> {
match self {
Key::Char(c) => Some(*c),
_ => None,
}
}
#[must_use]
pub fn matches(&self, c: char) -> bool {
matches!(self, Key::Char(k) if *k == c)
}
#[must_use]
pub fn matches_any(&self, chars: &[char]) -> bool {
match self {
Key::Char(c) => chars.contains(c),
_ => false,
}
}
}
impl From<KeyCode> for Key {
fn from(code: KeyCode) -> Self {
match code {
KeyCode::Char(c) => Key::Char(c),
KeyCode::F(n) => Key::F(n),
KeyCode::Backspace => Key::Backspace,
KeyCode::Enter => Key::Enter,
KeyCode::Left => Key::Left,
KeyCode::Right => Key::Right,
KeyCode::Up => Key::Up,
KeyCode::Down => Key::Down,
KeyCode::Home => Key::Home,
KeyCode::End => Key::End,
KeyCode::PageUp => Key::PageUp,
KeyCode::PageDown => Key::PageDown,
KeyCode::Tab => Key::Tab,
KeyCode::BackTab => Key::BackTab,
KeyCode::Delete => Key::Delete,
KeyCode::Insert => Key::Insert,
KeyCode::Esc => Key::Esc,
KeyCode::CapsLock => Key::CapsLock,
KeyCode::ScrollLock => Key::ScrollLock,
KeyCode::NumLock => Key::NumLock,
KeyCode::PrintScreen => Key::PrintScreen,
KeyCode::Pause => Key::Pause,
KeyCode::Menu => Key::Menu,
KeyCode::Null => Key::Null,
_ => Key::Null,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct KeyModifiers {
pub shift: bool,
pub ctrl: bool,
pub alt: bool,
pub super_key: bool,
}
impl KeyModifiers {
pub const NONE: Self = Self {
shift: false,
ctrl: false,
alt: false,
super_key: false,
};
pub const SHIFT: Self = Self {
shift: true,
ctrl: false,
alt: false,
super_key: false,
};
pub const CTRL: Self = Self {
shift: false,
ctrl: true,
alt: false,
super_key: false,
};
pub const ALT: Self = Self {
shift: false,
ctrl: false,
alt: true,
super_key: false,
};
#[must_use]
pub const fn any(&self) -> bool {
self.shift || self.ctrl || self.alt || self.super_key
}
#[must_use]
pub const fn none(&self) -> bool {
!self.any()
}
}
impl From<CrosstermModifiers> for KeyModifiers {
fn from(mods: CrosstermModifiers) -> Self {
Self {
shift: mods.contains(CrosstermModifiers::SHIFT),
ctrl: mods.contains(CrosstermModifiers::CONTROL),
alt: mods.contains(CrosstermModifiers::ALT),
super_key: mods.contains(CrosstermModifiers::SUPER),
}
}
}