use crcbl_core::KeyCode;
use crcbl_core::input::Keysym;
#[must_use]
pub const fn named_keysym(key: KeyCode) -> Option<Keysym> {
Some(match key {
KeyCode::Backspace => Keysym::BACKSPACE,
KeyCode::Tab => Keysym::TAB,
KeyCode::Enter => Keysym::RETURN,
KeyCode::Pause => Keysym::PAUSE,
KeyCode::ScrollLock => Keysym::SCROLL_LOCK,
KeyCode::Escape => Keysym::ESCAPE,
KeyCode::Home => Keysym::HOME,
KeyCode::ArrowLeft => Keysym::LEFT,
KeyCode::ArrowUp => Keysym::UP,
KeyCode::ArrowRight => Keysym::RIGHT,
KeyCode::ArrowDown => Keysym::DOWN,
KeyCode::PageUp => Keysym::PAGE_UP,
KeyCode::PageDown => Keysym::PAGE_DOWN,
KeyCode::End => Keysym::END,
KeyCode::PrintScreen => Keysym::PRINT,
KeyCode::Insert => Keysym::INSERT,
KeyCode::ContextMenu => Keysym::MENU,
KeyCode::NumLock => Keysym::NUM_LOCK,
KeyCode::NumpadEnter => Keysym::KP_ENTER,
KeyCode::NumpadMultiply => Keysym::KP_MULTIPLY,
KeyCode::NumpadAdd => Keysym::KP_ADD,
KeyCode::NumpadSubtract => Keysym::KP_SUBTRACT,
KeyCode::NumpadDecimal => Keysym::KP_DECIMAL,
KeyCode::NumpadDivide => Keysym::KP_DIVIDE,
KeyCode::Numpad0 => Keysym::KP_0,
KeyCode::Numpad1 => Keysym::KP_1,
KeyCode::Numpad2 => Keysym::KP_2,
KeyCode::Numpad3 => Keysym::KP_3,
KeyCode::Numpad4 => Keysym::KP_4,
KeyCode::Numpad5 => Keysym::KP_5,
KeyCode::Numpad6 => Keysym::KP_6,
KeyCode::Numpad7 => Keysym::KP_7,
KeyCode::Numpad8 => Keysym::KP_8,
KeyCode::Numpad9 => Keysym::KP_9,
KeyCode::F1 => Keysym::F1,
KeyCode::F2 => Keysym::F2,
KeyCode::F3 => Keysym::F3,
KeyCode::F4 => Keysym::F4,
KeyCode::F5 => Keysym::F5,
KeyCode::F6 => Keysym::F6,
KeyCode::F7 => Keysym::F7,
KeyCode::F8 => Keysym::F8,
KeyCode::F9 => Keysym::F9,
KeyCode::F10 => Keysym::F10,
KeyCode::F11 => Keysym::F11,
KeyCode::F12 => Keysym::F12,
KeyCode::ShiftLeft => Keysym::SHIFT_L,
KeyCode::ShiftRight => Keysym::SHIFT_R,
KeyCode::ControlLeft => Keysym::CONTROL_L,
KeyCode::ControlRight => Keysym::CONTROL_R,
KeyCode::CapsLock => Keysym::CAPS_LOCK,
KeyCode::AltLeft => Keysym::ALT_L,
KeyCode::AltRight => Keysym::ALT_R,
KeyCode::SuperLeft => Keysym::SUPER_L,
KeyCode::SuperRight => Keysym::SUPER_R,
KeyCode::Delete => Keysym::DELETE,
_ => return None,
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn named_keysyms_cover_the_keys_no_layout_can_move_and_no_others() {
assert_eq!(named_keysym(KeyCode::F1), Some(Keysym(0xFFBE)));
assert_eq!(named_keysym(KeyCode::Escape), Some(Keysym(0xFF1B)));
assert_eq!(named_keysym(KeyCode::SuperLeft), Some(Keysym(0xFFEB)));
assert_eq!(named_keysym(KeyCode::ShiftLeft), Some(Keysym(0xFFE1)));
assert_eq!(named_keysym(KeyCode::Numpad5), Some(Keysym(0xFFB5)));
assert_eq!(named_keysym(KeyCode::AltRight), Some(Keysym(0xFFEA)));
for key in KeyCode::ALL {
if let Some(keysym) = named_keysym(*key) {
assert_eq!(keysym.to_char(), None, "{key} is not a character key");
}
}
for key in [
KeyCode::KeyA,
KeyCode::Digit1,
KeyCode::Space,
KeyCode::Minus,
KeyCode::IntlYen,
] {
assert_eq!(named_keysym(key), None, "{key} depends on the layout");
}
}
#[test]
fn both_backends_re_export_the_shared_table() {
for key in KeyCode::ALL {
assert_eq!(
crate::appkit::keys::named_keysym(*key),
named_keysym(*key),
"{key}: the AppKit backend is not answering from the shared table",
);
assert_eq!(
crate::win32::keys::named_keysym(*key),
named_keysym(*key),
"{key}: the Win32 backend is not answering from the shared table",
);
}
}
}