use crossterm::event::{
Event, KeyCode, KeyEvent, KeyEventKind, KeyEventState, KeyModifiers as CrosstermKeyModifiers,
};
use crate::{error, key_repr::KeyValue};
use super::{Key, KeyModifiers};
mod key_value;
#[cfg(test)]
mod tests;
impl From<Key> for Event {
fn from(value: Key) -> Self {
let mut modifiers;
{
modifiers = CrosstermKeyModifiers::all();
if !value.modifiers.alt {
modifiers.remove(CrosstermKeyModifiers::ALT);
}
if !value.modifiers.ctrl {
modifiers.remove(CrosstermKeyModifiers::CONTROL);
}
if !value.modifiers.meta {
modifiers.remove(CrosstermKeyModifiers::META);
modifiers.remove(CrosstermKeyModifiers::SUPER);
}
if !value.modifiers.shift {
modifiers.remove(CrosstermKeyModifiers::SHIFT);
}
modifiers.remove(CrosstermKeyModifiers::HYPER);
modifiers.remove(CrosstermKeyModifiers::META);
if value.modifiers.alt
|| value.modifiers.ctrl
|| value.modifiers.meta
|| value.modifiers.shift
{
modifiers.remove(CrosstermKeyModifiers::NONE);
}
}
Event::Key(KeyEvent {
code: {
if let KeyValue::Char(char) = value.value {
KeyCode::Char(char)
} else {
value.value.into()
}
},
modifiers,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
})
}
}
impl TryFrom<&Event> for Key {
type Error = error::KeyFromCrossterm;
fn try_from(value: &Event) -> Result<Self, Self::Error> {
match value {
Event::Key(key_event) => {
let mut modifiers = KeyModifiers::default();
{
let key_mods = key_event.modifiers;
modifiers.alt =
CrosstermKeyModifiers::intersects(&key_mods, CrosstermKeyModifiers::ALT);
modifiers.ctrl = CrosstermKeyModifiers::intersects(
&key_mods,
CrosstermKeyModifiers::CONTROL,
);
modifiers.meta =
CrosstermKeyModifiers::intersects(&key_mods, CrosstermKeyModifiers::META)
|| CrosstermKeyModifiers::intersects(
&key_mods,
CrosstermKeyModifiers::SUPER,
);
modifiers.shift =
CrosstermKeyModifiers::intersects(&key_mods, CrosstermKeyModifiers::SHIFT);
}
let output_key = Key {
value: key_event.code.into(),
modifiers,
};
Ok(output_key)
}
event => Err(error::KeyFromCrossterm::OnlyKey(event.to_owned())),
}
}
}