1use std::{fmt, mem};
2
3use crate::{event::Key, raw::input::input_keymap_entry};
4
5#[derive(Clone, Copy)]
17#[repr(transparent)]
18pub struct KeymapEntry(pub(crate) input_keymap_entry);
19
20impl KeymapEntry {
21 pub(crate) fn zeroed() -> Self {
22 unsafe { mem::zeroed() }
23 }
24
25 pub fn index(&self) -> u16 {
27 self.0.index
28 }
29
30 pub fn keycode(&self) -> Key {
32 let key = self.0.keycode as u16;
33 Key::from_raw(key)
34 }
35
36 pub fn scancode(&self) -> Scancode {
43 let len = self.0.len.min(32);
44 Scancode::from_ne_slice(&self.0.scancode[..len as usize])
45 }
46}
47
48impl fmt::Debug for KeymapEntry {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 f.debug_struct("KeymapEntry")
51 .field("index", &self.index())
52 .field("keycode", &self.keycode())
53 .field("scancode", &self.scancode())
54 .finish()
55 }
56}
57
58#[derive(Clone, Copy)]
87pub struct Scancode {
88 pub(crate) len: u8,
90 pub(crate) bytes: [u8; 32],
92}
93
94impl Scancode {
95 fn from_ne_slice(bytes: &[u8]) -> Self {
96 assert!(bytes.len() <= 32);
97 let mut a = [0; 32];
98 a[..bytes.len()].copy_from_slice(&bytes);
99 Self {
100 len: bytes.len() as u8,
101 bytes: a,
102 }
103 }
104
105 fn as_ne_bytes(&self) -> &[u8] {
106 &self.bytes[..self.len as usize]
107 }
108
109 fn iter_ne_bytes(&self) -> impl DoubleEndedIterator<Item = u8> {
110 self.as_ne_bytes().iter().copied()
111 }
112 fn iter_be_bytes(&self) -> impl Iterator<Item = u8> {
113 #[cfg(target_endian = "little")]
114 return self.iter_ne_bytes().rev();
115
116 #[cfg(target_endian = "big")]
117 return self.iter_ne_bytes();
118 }
119}
120
121impl From<u8> for Scancode {
122 fn from(value: u8) -> Self {
123 Self::from_ne_slice(&[value])
124 }
125}
126impl From<u16> for Scancode {
127 fn from(value: u16) -> Self {
128 Self::from_ne_slice(&value.to_ne_bytes())
129 }
130}
131impl From<u32> for Scancode {
132 fn from(value: u32) -> Self {
133 Self::from_ne_slice(&value.to_ne_bytes())
134 }
135}
136
137impl fmt::Debug for Scancode {
138 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139 for (i, byte) in self.iter_be_bytes().skip_while(|b| *b == 0).enumerate() {
140 if i == 0 {
141 write!(f, "{byte:x}")?;
142 } else {
143 write!(f, "{byte:02x}")?;
144 }
145 }
146 Ok(())
147 }
148}
149impl fmt::Display for Scancode {
150 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151 <Self as fmt::Debug>::fmt(self, f)
152 }
153}
154
155#[cfg(test)]
156mod tests {
157 use super::*;
158
159 #[test]
160 #[cfg_attr(target_endian = "big", ignore = "little-endian test")]
161 fn scancode_debug() {
162 let code = Scancode::from_ne_slice(&[0xe0, 0x00, 0x07]);
163 assert_eq!(format!("{code:?}"), "700e0");
164
165 let code = Scancode::from_ne_slice(&[0xe0, 0x00, 0x07, 0x00]);
166 assert_eq!(format!("{code:?}"), "700e0");
167 }
168}