pub use super::generated_api::api::key::{ key::{ KeyModifier as ProtobufKeyModifier, MainKey as ProtobufMainKey, NamedKey as ProtobufNamedKey, }, Key as ProtobufKey, }; use crate::data::{BareKey, KeyModifier, KeyWithModifier}; use std::collections::BTreeSet; use std::convert::TryFrom; impl TryFrom for BareKey { type Error = &'static str; fn try_from(protobuf_main_key: ProtobufMainKey) -> Result { match protobuf_main_key { ProtobufMainKey::Char(character) => Ok(BareKey::Char(char_index_to_char(character))), ProtobufMainKey::Key(key_index) => { let key = ProtobufNamedKey::from_i32(key_index).ok_or("invalid_key")?; Ok(named_key_to_bare_key(key)) }, } } } impl TryFrom for ProtobufMainKey { type Error = &'static str; fn try_from(bare_key: BareKey) -> Result { match bare_key { BareKey::PageDown => Ok(ProtobufMainKey::Key(ProtobufNamedKey::PageDown as i32)), BareKey::PageUp => Ok(ProtobufMainKey::Key(ProtobufNamedKey::PageUp as i32)), BareKey::Left => Ok(ProtobufMainKey::Key(ProtobufNamedKey::LeftArrow as i32)), BareKey::Down => Ok(ProtobufMainKey::Key(ProtobufNamedKey::DownArrow as i32)), BareKey::Up => Ok(ProtobufMainKey::Key(ProtobufNamedKey::UpArrow as i32)), BareKey::Right => Ok(ProtobufMainKey::Key(ProtobufNamedKey::RightArrow as i32)), BareKey::Home => Ok(ProtobufMainKey::Key(ProtobufNamedKey::Home as i32)), BareKey::End => Ok(ProtobufMainKey::Key(ProtobufNamedKey::End as i32)), BareKey::Backspace => Ok(ProtobufMainKey::Key(ProtobufNamedKey::Backspace as i32)), BareKey::Delete => Ok(ProtobufMainKey::Key(ProtobufNamedKey::Delete as i32)), BareKey::Insert => Ok(ProtobufMainKey::Key(ProtobufNamedKey::Insert as i32)), BareKey::F(f_index) => fn_index_to_main_key(f_index), BareKey::Char(character) => Ok(ProtobufMainKey::Char(character as i32)), BareKey::Tab => Ok(ProtobufMainKey::Key(ProtobufNamedKey::Tab as i32)), BareKey::Esc => Ok(ProtobufMainKey::Key(ProtobufNamedKey::Esc as i32)), BareKey::Enter => Ok(ProtobufMainKey::Key(ProtobufNamedKey::Enter as i32)), BareKey::CapsLock => Ok(ProtobufMainKey::Key(ProtobufNamedKey::CapsLock as i32)), BareKey::ScrollLock => Ok(ProtobufMainKey::Key(ProtobufNamedKey::ScrollLock as i32)), BareKey::NumLock => Ok(ProtobufMainKey::Key(ProtobufNamedKey::NumLock as i32)), BareKey::PrintScreen => Ok(ProtobufMainKey::Key(ProtobufNamedKey::PrintScreen as i32)), BareKey::Pause => Ok(ProtobufMainKey::Key(ProtobufNamedKey::Pause as i32)), BareKey::Menu => Ok(ProtobufMainKey::Key(ProtobufNamedKey::Menu as i32)), } } } impl TryFrom for KeyModifier { type Error = &'static str; fn try_from(protobuf_key_modifier: ProtobufKeyModifier) -> Result { match protobuf_key_modifier { ProtobufKeyModifier::Ctrl => Ok(KeyModifier::Ctrl), ProtobufKeyModifier::Alt => Ok(KeyModifier::Alt), ProtobufKeyModifier::Shift => Ok(KeyModifier::Shift), ProtobufKeyModifier::Super => Ok(KeyModifier::Super), } } } impl TryFrom for ProtobufKeyModifier { type Error = &'static str; fn try_from(key_modifier: KeyModifier) -> Result { match key_modifier { KeyModifier::Ctrl => Ok(ProtobufKeyModifier::Ctrl), KeyModifier::Alt => Ok(ProtobufKeyModifier::Alt), KeyModifier::Shift => Ok(ProtobufKeyModifier::Shift), KeyModifier::Super => Ok(ProtobufKeyModifier::Super), } } } impl TryFrom for KeyWithModifier { type Error = &'static str; fn try_from(protobuf_key: ProtobufKey) -> Result { let bare_key = protobuf_key .main_key .ok_or("Key must have main_key")? .try_into()?; let mut key_modifiers = BTreeSet::new(); if let Some(main_modifier) = protobuf_key.modifier { key_modifiers.insert( ProtobufKeyModifier::from_i32(main_modifier) .ok_or("invalid key modifier")? .try_into()?, ); } for key_modifier in protobuf_key.additional_modifiers { key_modifiers.insert( ProtobufKeyModifier::from_i32(key_modifier) .ok_or("invalid key modifier")? .try_into()?, ); } Ok(KeyWithModifier { bare_key, key_modifiers, }) } } impl TryFrom for ProtobufKey { type Error = &'static str; fn try_from(key_with_modifier: KeyWithModifier) -> Result { let mut modifiers: Vec = vec![]; for key_modifier in key_with_modifier.key_modifiers { modifiers.push(key_modifier.try_into()?); } Ok(ProtobufKey { main_key: Some(key_with_modifier.bare_key.try_into()?), modifier: modifiers.pop().map(|m| m as i32), additional_modifiers: modifiers.into_iter().map(|m| m as i32).collect(), }) } } fn fn_index_to_main_key(index: u8) -> Result { match index { 1 => Ok(ProtobufMainKey::Key(ProtobufNamedKey::F1 as i32)), 2 => Ok(ProtobufMainKey::Key(ProtobufNamedKey::F2 as i32)), 3 => Ok(ProtobufMainKey::Key(ProtobufNamedKey::F3 as i32)), 4 => Ok(ProtobufMainKey::Key(ProtobufNamedKey::F4 as i32)), 5 => Ok(ProtobufMainKey::Key(ProtobufNamedKey::F5 as i32)), 6 => Ok(ProtobufMainKey::Key(ProtobufNamedKey::F6 as i32)), 7 => Ok(ProtobufMainKey::Key(ProtobufNamedKey::F7 as i32)), 8 => Ok(ProtobufMainKey::Key(ProtobufNamedKey::F8 as i32)), 9 => Ok(ProtobufMainKey::Key(ProtobufNamedKey::F9 as i32)), 10 => Ok(ProtobufMainKey::Key(ProtobufNamedKey::F10 as i32)), 11 => Ok(ProtobufMainKey::Key(ProtobufNamedKey::F11 as i32)), 12 => Ok(ProtobufMainKey::Key(ProtobufNamedKey::F12 as i32)), _ => Err("Invalid key"), } } fn char_index_to_char(char_index: i32) -> char { char_index as u8 as char } fn named_key_to_bare_key(named_key: ProtobufNamedKey) -> BareKey { match named_key { ProtobufNamedKey::PageDown => BareKey::PageDown, ProtobufNamedKey::PageUp => BareKey::PageUp, ProtobufNamedKey::LeftArrow => BareKey::Left, ProtobufNamedKey::DownArrow => BareKey::Down, ProtobufNamedKey::UpArrow => BareKey::Up, ProtobufNamedKey::RightArrow => BareKey::Right, ProtobufNamedKey::Home => BareKey::Home, ProtobufNamedKey::End => BareKey::End, ProtobufNamedKey::Backspace => BareKey::Backspace, ProtobufNamedKey::Delete => BareKey::Delete, ProtobufNamedKey::Insert => BareKey::Insert, ProtobufNamedKey::F1 => BareKey::F(1), ProtobufNamedKey::F2 => BareKey::F(2), ProtobufNamedKey::F3 => BareKey::F(3), ProtobufNamedKey::F4 => BareKey::F(4), ProtobufNamedKey::F5 => BareKey::F(5), ProtobufNamedKey::F6 => BareKey::F(6), ProtobufNamedKey::F7 => BareKey::F(7), ProtobufNamedKey::F8 => BareKey::F(8), ProtobufNamedKey::F9 => BareKey::F(9), ProtobufNamedKey::F10 => BareKey::F(10), ProtobufNamedKey::F11 => BareKey::F(11), ProtobufNamedKey::F12 => BareKey::F(12), ProtobufNamedKey::Tab => BareKey::Tab, ProtobufNamedKey::Esc => BareKey::Esc, ProtobufNamedKey::CapsLock => BareKey::CapsLock, ProtobufNamedKey::ScrollLock => BareKey::ScrollLock, ProtobufNamedKey::PrintScreen => BareKey::PrintScreen, ProtobufNamedKey::Pause => BareKey::Pause, ProtobufNamedKey::Menu => BareKey::Menu, ProtobufNamedKey::NumLock => BareKey::NumLock, ProtobufNamedKey::Enter => BareKey::Enter, } }