1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#![doc(html_playground_url = "https://play.rust-lang.org/")]
//! key-mapping library allows for keyboard key code conversion between systems such as the DOM and
//! HID usage-ids. With Rust `[no_std]` support.
//!
//! # Features
//!
//! Extra functionality is behind optional features to optimize compile time and binary size.
//!
//! - **`std`** *(enabled by default)* - Add support for Rust's libstd types.
//! - **`serde`** Add support for `serde` de/serializing library.
//!
//! # Example Usage
//!
//! ```toml
//! [dependencies]
//! key-mapping = "0.1"
//! ```
//!
//! ```rust,editable
//! use key_mapping::Keyboard;
//!
//! fn main() {
//!     let dom_code = "KeyA";
//!     let usage_id = Keyboard::US.dom_key_to_usage_id(dom_code).unwrap();
//!
//!     assert_eq!(0x04, *usage_id);
//! }
//! ```

#![forbid(unsafe_code)]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

include!(concat!(env!("OUT_DIR"), "/codegen.rs"));

/// Keyboard layouts, used to convert between key-code types.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Keyboard {
    /// US keyboard layout *(default)*
    #[default]
    US,
    /// UK keyboard layout
    UK,
}

impl Keyboard {
    /// Convert key-code into a hid usage id, using the given keyboard layout.
    /// Uses a performant O(1) operation.
    pub fn dom_key_to_usage_id(&self, key_code: &str) -> Option<&u8> {
        match self {
            Self::US => DOM_KEYS_US.get(key_code),
            Self::UK => DOM_KEYS_UK.get(key_code),
        }
    }
}

/// A single mapped keyboard key.
#[derive(Debug, Clone, Copy)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct MappedKey<'a> {
    /// HID usage-id for keyboard key
    pub usage_id: u8,
    /// The DOM key representation
    pub dom_key: &'a str,
    /// Machine friendly key name
    pub prefix: &'a str,
}

#[cfg(test)]
mod tests {
    use crate::Keyboard;

    #[test]
    fn dom_key_to_hid() {
        assert_eq!(0x04, *Keyboard::US.dom_key_to_usage_id("KeyA").unwrap());
        assert_eq!(
            0x31,
            *Keyboard::US.dom_key_to_usage_id("Backslash").unwrap()
        );
        assert_eq!(
            0x32,
            *Keyboard::UK.dom_key_to_usage_id("Backslash").unwrap()
        );
    }
}