use crate::*; pub trait Command: Sized { fn run (&self, state: &mut T) -> Perhaps; } pub const fn key (code: KeyCode) -> KeyEvent { KeyEvent { code, modifiers: KeyModifiers::NONE, kind: crossterm::event::KeyEventKind::Press, state: crossterm::event::KeyEventState::NONE } } pub const fn ctrl (key: KeyEvent) -> KeyEvent { KeyEvent { modifiers: key.modifiers.union(KeyModifiers::CONTROL), ..key } } pub const fn alt (key: KeyEvent) -> KeyEvent { KeyEvent { modifiers: key.modifiers.union(KeyModifiers::ALT), ..key } } pub const fn shift (key: KeyEvent) -> KeyEvent { KeyEvent { modifiers: key.modifiers.union(KeyModifiers::SHIFT), ..key } } pub trait HandleKey + 'static>: Sized { const HANDLE_KEY_MAP: &'static [(KeyEvent, C)] = &[]; // FIXME: needs to be method #[inline] fn match_input (from: &TuiInput) -> Option<&'static C> { if let TuiEvent::Input(crossterm::event::Event::Key(key)) = from.event() { return Self::match_key_static(&key) } None } #[inline] fn match_key_static (key: &KeyEvent) -> Option<&'static C> { for (binding, command) in Self::HANDLE_KEY_MAP.iter() { if key == binding { return Some(command); } } None } #[inline] fn match_key (&self, key: &KeyEvent) -> Option<&'static C> { Self::match_key_static(key) } #[inline] fn handle_key (&mut self, key: &KeyEvent) -> Perhaps { if let Some(command) = self.match_key(key) { command.run(self) } else { Ok(None) } } }