gled-ui 2.31.0

gled's egui interface, shared by the desktop app and the browser
Documentation
//! Conversions between egui's `Key` and gled's `KeyCode`. Both matches are
//! exhaustive, so a key added to egui is a compile error here instead of a key
//! that silently cannot be assigned.

use egui::Key;

use gled_model::input::key_code::KeyCode;

/// egui's key for a stored key.
#[cfg(test)]
fn egui_key(key: KeyCode) -> Key {
    match key {
        KeyCode::ArrowDown => Key::ArrowDown,
        KeyCode::ArrowLeft => Key::ArrowLeft,
        KeyCode::ArrowRight => Key::ArrowRight,
        KeyCode::ArrowUp => Key::ArrowUp,
        KeyCode::Escape => Key::Escape,
        KeyCode::Tab => Key::Tab,
        KeyCode::Backspace => Key::Backspace,
        KeyCode::Enter => Key::Enter,
        KeyCode::Space => Key::Space,
        KeyCode::Insert => Key::Insert,
        KeyCode::Delete => Key::Delete,
        KeyCode::Home => Key::Home,
        KeyCode::End => Key::End,
        KeyCode::PageUp => Key::PageUp,
        KeyCode::PageDown => Key::PageDown,
        KeyCode::Copy => Key::Copy,
        KeyCode::Cut => Key::Cut,
        KeyCode::Paste => Key::Paste,
        KeyCode::Colon => Key::Colon,
        KeyCode::Comma => Key::Comma,
        KeyCode::Backslash => Key::Backslash,
        KeyCode::Slash => Key::Slash,
        KeyCode::Pipe => Key::Pipe,
        KeyCode::Questionmark => Key::Questionmark,
        KeyCode::Exclamationmark => Key::Exclamationmark,
        KeyCode::OpenBracket => Key::OpenBracket,
        KeyCode::CloseBracket => Key::CloseBracket,
        KeyCode::OpenCurlyBracket => Key::OpenCurlyBracket,
        KeyCode::CloseCurlyBracket => Key::CloseCurlyBracket,
        KeyCode::Backtick => Key::Backtick,
        KeyCode::Minus => Key::Minus,
        KeyCode::Period => Key::Period,
        KeyCode::Plus => Key::Plus,
        KeyCode::Equals => Key::Equals,
        KeyCode::Semicolon => Key::Semicolon,
        KeyCode::Quote => Key::Quote,
        KeyCode::Num0 => Key::Num0,
        KeyCode::Num1 => Key::Num1,
        KeyCode::Num2 => Key::Num2,
        KeyCode::Num3 => Key::Num3,
        KeyCode::Num4 => Key::Num4,
        KeyCode::Num5 => Key::Num5,
        KeyCode::Num6 => Key::Num6,
        KeyCode::Num7 => Key::Num7,
        KeyCode::Num8 => Key::Num8,
        KeyCode::Num9 => Key::Num9,
        KeyCode::A => Key::A,
        KeyCode::B => Key::B,
        KeyCode::C => Key::C,
        KeyCode::D => Key::D,
        KeyCode::E => Key::E,
        KeyCode::F => Key::F,
        KeyCode::G => Key::G,
        KeyCode::H => Key::H,
        KeyCode::I => Key::I,
        KeyCode::J => Key::J,
        KeyCode::K => Key::K,
        KeyCode::L => Key::L,
        KeyCode::M => Key::M,
        KeyCode::N => Key::N,
        KeyCode::O => Key::O,
        KeyCode::P => Key::P,
        KeyCode::Q => Key::Q,
        KeyCode::R => Key::R,
        KeyCode::S => Key::S,
        KeyCode::T => Key::T,
        KeyCode::U => Key::U,
        KeyCode::V => Key::V,
        KeyCode::W => Key::W,
        KeyCode::X => Key::X,
        KeyCode::Y => Key::Y,
        KeyCode::Z => Key::Z,
        KeyCode::F1 => Key::F1,
        KeyCode::F2 => Key::F2,
        KeyCode::F3 => Key::F3,
        KeyCode::F4 => Key::F4,
        KeyCode::F5 => Key::F5,
        KeyCode::F6 => Key::F6,
        KeyCode::F7 => Key::F7,
        KeyCode::F8 => Key::F8,
        KeyCode::F9 => Key::F9,
        KeyCode::F10 => Key::F10,
        KeyCode::F11 => Key::F11,
        KeyCode::F12 => Key::F12,
        KeyCode::F13 => Key::F13,
        KeyCode::F14 => Key::F14,
        KeyCode::F15 => Key::F15,
        KeyCode::F16 => Key::F16,
        KeyCode::F17 => Key::F17,
        KeyCode::F18 => Key::F18,
        KeyCode::F19 => Key::F19,
        KeyCode::F20 => Key::F20,
        KeyCode::F21 => Key::F21,
        KeyCode::F22 => Key::F22,
        KeyCode::F23 => Key::F23,
        KeyCode::F24 => Key::F24,
        KeyCode::F25 => Key::F25,
        KeyCode::F26 => Key::F26,
        KeyCode::F27 => Key::F27,
        KeyCode::F28 => Key::F28,
        KeyCode::F29 => Key::F29,
        KeyCode::F30 => Key::F30,
        KeyCode::F31 => Key::F31,
        KeyCode::F32 => Key::F32,
        KeyCode::F33 => Key::F33,
        KeyCode::F34 => Key::F34,
        KeyCode::F35 => Key::F35,
        KeyCode::BrowserBack => Key::BrowserBack,
        KeyCode::ShiftLeft => Key::ShiftLeft,
        KeyCode::ShiftRight => Key::ShiftRight,
        KeyCode::ControlLeft => Key::ControlLeft,
        KeyCode::ControlRight => Key::ControlRight,
        KeyCode::AltLeft => Key::AltLeft,
        KeyCode::AltRight => Key::AltRight,
        KeyCode::SuperLeft => Key::SuperLeft,
        KeyCode::SuperRight => Key::SuperRight,
        KeyCode::IntlBackslash => Key::IntlBackslash,
    }
}

/// The stored form of an egui key.
pub(crate) fn key_code(key: Key) -> KeyCode {
    match key {
        Key::ArrowDown => KeyCode::ArrowDown,
        Key::ArrowLeft => KeyCode::ArrowLeft,
        Key::ArrowRight => KeyCode::ArrowRight,
        Key::ArrowUp => KeyCode::ArrowUp,
        Key::Escape => KeyCode::Escape,
        Key::Tab => KeyCode::Tab,
        Key::Backspace => KeyCode::Backspace,
        Key::Enter => KeyCode::Enter,
        Key::Space => KeyCode::Space,
        Key::Insert => KeyCode::Insert,
        Key::Delete => KeyCode::Delete,
        Key::Home => KeyCode::Home,
        Key::End => KeyCode::End,
        Key::PageUp => KeyCode::PageUp,
        Key::PageDown => KeyCode::PageDown,
        Key::Copy => KeyCode::Copy,
        Key::Cut => KeyCode::Cut,
        Key::Paste => KeyCode::Paste,
        Key::Colon => KeyCode::Colon,
        Key::Comma => KeyCode::Comma,
        Key::Backslash => KeyCode::Backslash,
        Key::Slash => KeyCode::Slash,
        Key::Pipe => KeyCode::Pipe,
        Key::Questionmark => KeyCode::Questionmark,
        Key::Exclamationmark => KeyCode::Exclamationmark,
        Key::OpenBracket => KeyCode::OpenBracket,
        Key::CloseBracket => KeyCode::CloseBracket,
        Key::OpenCurlyBracket => KeyCode::OpenCurlyBracket,
        Key::CloseCurlyBracket => KeyCode::CloseCurlyBracket,
        Key::Backtick => KeyCode::Backtick,
        Key::Minus => KeyCode::Minus,
        Key::Period => KeyCode::Period,
        Key::Plus => KeyCode::Plus,
        Key::Equals => KeyCode::Equals,
        Key::Semicolon => KeyCode::Semicolon,
        Key::Quote => KeyCode::Quote,
        Key::Num0 => KeyCode::Num0,
        Key::Num1 => KeyCode::Num1,
        Key::Num2 => KeyCode::Num2,
        Key::Num3 => KeyCode::Num3,
        Key::Num4 => KeyCode::Num4,
        Key::Num5 => KeyCode::Num5,
        Key::Num6 => KeyCode::Num6,
        Key::Num7 => KeyCode::Num7,
        Key::Num8 => KeyCode::Num8,
        Key::Num9 => KeyCode::Num9,
        Key::A => KeyCode::A,
        Key::B => KeyCode::B,
        Key::C => KeyCode::C,
        Key::D => KeyCode::D,
        Key::E => KeyCode::E,
        Key::F => KeyCode::F,
        Key::G => KeyCode::G,
        Key::H => KeyCode::H,
        Key::I => KeyCode::I,
        Key::J => KeyCode::J,
        Key::K => KeyCode::K,
        Key::L => KeyCode::L,
        Key::M => KeyCode::M,
        Key::N => KeyCode::N,
        Key::O => KeyCode::O,
        Key::P => KeyCode::P,
        Key::Q => KeyCode::Q,
        Key::R => KeyCode::R,
        Key::S => KeyCode::S,
        Key::T => KeyCode::T,
        Key::U => KeyCode::U,
        Key::V => KeyCode::V,
        Key::W => KeyCode::W,
        Key::X => KeyCode::X,
        Key::Y => KeyCode::Y,
        Key::Z => KeyCode::Z,
        Key::F1 => KeyCode::F1,
        Key::F2 => KeyCode::F2,
        Key::F3 => KeyCode::F3,
        Key::F4 => KeyCode::F4,
        Key::F5 => KeyCode::F5,
        Key::F6 => KeyCode::F6,
        Key::F7 => KeyCode::F7,
        Key::F8 => KeyCode::F8,
        Key::F9 => KeyCode::F9,
        Key::F10 => KeyCode::F10,
        Key::F11 => KeyCode::F11,
        Key::F12 => KeyCode::F12,
        Key::F13 => KeyCode::F13,
        Key::F14 => KeyCode::F14,
        Key::F15 => KeyCode::F15,
        Key::F16 => KeyCode::F16,
        Key::F17 => KeyCode::F17,
        Key::F18 => KeyCode::F18,
        Key::F19 => KeyCode::F19,
        Key::F20 => KeyCode::F20,
        Key::F21 => KeyCode::F21,
        Key::F22 => KeyCode::F22,
        Key::F23 => KeyCode::F23,
        Key::F24 => KeyCode::F24,
        Key::F25 => KeyCode::F25,
        Key::F26 => KeyCode::F26,
        Key::F27 => KeyCode::F27,
        Key::F28 => KeyCode::F28,
        Key::F29 => KeyCode::F29,
        Key::F30 => KeyCode::F30,
        Key::F31 => KeyCode::F31,
        Key::F32 => KeyCode::F32,
        Key::F33 => KeyCode::F33,
        Key::F34 => KeyCode::F34,
        Key::F35 => KeyCode::F35,
        Key::BrowserBack => KeyCode::BrowserBack,
        Key::ShiftLeft => KeyCode::ShiftLeft,
        Key::ShiftRight => KeyCode::ShiftRight,
        Key::ControlLeft => KeyCode::ControlLeft,
        Key::ControlRight => KeyCode::ControlRight,
        Key::AltLeft => KeyCode::AltLeft,
        Key::AltRight => KeyCode::AltRight,
        Key::SuperLeft => KeyCode::SuperLeft,
        Key::SuperRight => KeyCode::SuperRight,
        Key::IntlBackslash => KeyCode::IntlBackslash,
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use strum::VariantArray;

    #[test]
    fn mirrors_egui_keys_with_the_same_serde_names_and_order() {
        assert_eq!(Key::ALL.len(), KeyCode::VARIANTS.len());
        for key in Key::ALL {
            let code = key_code(*key);
            assert_eq!(egui_key(code), *key);
            assert_eq!(
                serde_json::to_string(key).expect("egui key serializes"),
                serde_json::to_string(&code).expect("key code serializes")
            );
            assert_eq!(format!("{key:?}"), format!("{code:?}"));
        }
        // Ordering decides the order of input events in a set.
        for a in Key::ALL {
            for b in Key::ALL {
                assert_eq!(a.cmp(b), key_code(*a).cmp(&key_code(*b)));
            }
        }
        let mut sorted = KeyCode::VARIANTS.to_vec();
        sorted.sort();
        assert_eq!(sorted, KeyCode::VARIANTS);
    }
}