Skip to main content

rmk_types/
led_indicator.rs

1//! LED indicator.
2//!
3//! This module handles keyboard LED indicators such as Caps Lock, Num Lock,
4//! and Scroll Lock. It provides efficient bitfield operations for these indicators.
5use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not};
6
7use bitfield_struct::bitfield;
8use postcard::experimental::max_size::MaxSize;
9
10/// Indicators defined in the HID spec 11.1
11#[derive(Debug)]
12#[cfg_attr(feature = "defmt", derive(defmt::Format))]
13pub enum LedIndicatorType {
14    NumLock,
15    CapsLock,
16    ScrollLock,
17    Compose,
18    Kana,
19}
20
21#[bitfield(u8, defmt = cfg(feature = "defmt"))]
22#[derive(Eq, PartialEq, MaxSize)]
23pub struct LedIndicator {
24    #[bits(1)]
25    pub num_lock: bool,
26    #[bits(1)]
27    pub caps_lock: bool,
28    #[bits(1)]
29    pub scroll_lock: bool,
30    #[bits(1)]
31    pub compose: bool,
32    #[bits(1)]
33    pub kana: bool,
34    #[bits(3)]
35    _reserved: u8,
36}
37
38// u8 on the wire (postcard); named bools on serde-wasm-bindgen / serde_json (TS).
39crate::bitfield_named_serde!(LedIndicator, "LedIndicator", {
40    num_lock = with_num_lock,
41    caps_lock = with_caps_lock,
42    scroll_lock = with_scroll_lock,
43    compose = with_compose,
44    kana = with_kana,
45});
46
47impl BitOr for LedIndicator {
48    type Output = Self;
49
50    fn bitor(self, rhs: Self) -> Self::Output {
51        Self::from_bits(self.into_bits() | rhs.into_bits())
52    }
53}
54
55impl BitAnd for LedIndicator {
56    type Output = Self;
57
58    fn bitand(self, rhs: Self) -> Self::Output {
59        Self::from_bits(self.into_bits() & rhs.into_bits())
60    }
61}
62
63impl Not for LedIndicator {
64    type Output = Self;
65
66    fn not(self) -> Self::Output {
67        Self::from_bits(!self.into_bits())
68    }
69}
70
71impl BitAndAssign for LedIndicator {
72    fn bitand_assign(&mut self, rhs: Self) {
73        *self = *self & rhs;
74    }
75}
76
77impl BitOrAssign for LedIndicator {
78    fn bitor_assign(&mut self, rhs: Self) {
79        *self = *self | rhs;
80    }
81}
82
83impl LedIndicator {
84    pub const NUM_LOCK: Self = Self::new().with_num_lock(true);
85    pub const CAPS_LOCK: Self = Self::new().with_caps_lock(true);
86    pub const SCROLL_LOCK: Self = Self::new().with_scroll_lock(true);
87    pub const COMPOSE: Self = Self::new().with_compose(true);
88    pub const KANA: Self = Self::new().with_kana(true);
89
90    pub const fn new_from(num_lock: bool, caps_lock: bool, scroll_lock: bool, compose: bool, kana: bool) -> Self {
91        Self::new()
92            .with_num_lock(num_lock)
93            .with_caps_lock(caps_lock)
94            .with_scroll_lock(scroll_lock)
95            .with_compose(compose)
96            .with_kana(kana)
97    }
98}