openlogi_device_registry/
receiver.rs1use crate::LOGITECH_VENDOR_ID;
4
5#[derive(Clone, Copy, Debug, Eq, PartialEq)]
7pub enum ReceiverBrand {
8 Bolt,
10 Unifying,
12 Nano,
14 Lightspeed,
16}
17
18#[derive(Clone, Copy, Debug, Eq, PartialEq)]
20pub enum ReceiverProtocol {
21 Bolt,
23 Unifying,
25}
26
27#[derive(Clone, Copy, Debug, Eq, PartialEq)]
29pub struct ReceiverDescriptor {
30 pub vendor_id: u16,
32 pub product_id: u16,
34 pub brand: ReceiverBrand,
36 pub protocol: ReceiverProtocol,
38}
39
40impl ReceiverDescriptor {
41 const fn logitech(product_id: u16, brand: ReceiverBrand, protocol: ReceiverProtocol) -> Self {
42 Self {
43 vendor_id: LOGITECH_VENDOR_ID,
44 product_id,
45 brand,
46 protocol,
47 }
48 }
49}
50
51pub const RECEIVERS: &[ReceiverDescriptor] = &[
58 ReceiverDescriptor::logitech(0xc52b, ReceiverBrand::Unifying, ReceiverProtocol::Unifying),
59 ReceiverDescriptor::logitech(0xc532, ReceiverBrand::Unifying, ReceiverProtocol::Unifying),
60 ReceiverDescriptor::logitech(0xc534, ReceiverBrand::Nano, ReceiverProtocol::Unifying),
64 ReceiverDescriptor::logitech(0xc537, ReceiverBrand::Nano, ReceiverProtocol::Unifying),
66 ReceiverDescriptor::logitech(
69 0xc539,
70 ReceiverBrand::Lightspeed,
71 ReceiverProtocol::Unifying,
72 ),
73 ReceiverDescriptor::logitech(
75 0xc53f,
76 ReceiverBrand::Lightspeed,
77 ReceiverProtocol::Unifying,
78 ),
79 ReceiverDescriptor::logitech(
81 0xc547,
82 ReceiverBrand::Lightspeed,
83 ReceiverProtocol::Unifying,
84 ),
85 ReceiverDescriptor::logitech(0xc548, ReceiverBrand::Bolt, ReceiverProtocol::Bolt),
86 ReceiverDescriptor::logitech(
88 0xc54d,
89 ReceiverBrand::Lightspeed,
90 ReceiverProtocol::Unifying,
91 ),
92];
93
94#[must_use]
96pub fn find_receiver(vendor_id: u16, product_id: u16) -> Option<&'static ReceiverDescriptor> {
97 RECEIVERS
98 .iter()
99 .find(|receiver| receiver.vendor_id == vendor_id && receiver.product_id == product_id)
100}
101
102#[cfg(test)]
103mod tests {
104 use super::{RECEIVERS, ReceiverBrand, ReceiverProtocol, find_receiver};
105 use crate::LOGITECH_VENDOR_ID;
106
107 #[test]
108 fn receiver_identities_are_unique() {
109 for (index, receiver) in RECEIVERS.iter().enumerate() {
110 assert!(
111 RECEIVERS[..index].iter().all(|other| {
112 (other.vendor_id, other.product_id) != (receiver.vendor_id, receiver.product_id)
113 }),
114 "duplicate receiver identity {:04x}:{:04x}",
115 receiver.vendor_id,
116 receiver.product_id
117 );
118 }
119 }
120
121 #[test]
122 fn superlight_dex_receiver_is_lightspeed_over_unifying_protocol() {
123 let receiver = find_receiver(LOGITECH_VENDOR_ID, 0xc54d).expect("c54d receiver");
124
125 assert_eq!(receiver.brand, ReceiverBrand::Lightspeed);
126 assert_eq!(receiver.protocol, ReceiverProtocol::Unifying);
127 }
128
129 #[test]
130 fn mk270_mk295_nano_receiver_is_nano_over_unifying_protocol() {
131 let receiver = find_receiver(LOGITECH_VENDOR_ID, 0xc534).expect("c534 receiver");
132
133 assert_eq!(receiver.brand, ReceiverBrand::Nano);
134 assert_eq!(receiver.protocol, ReceiverProtocol::Unifying);
135 }
136
137 #[test]
138 fn lookup_requires_the_matching_vendor() {
139 assert!(find_receiver(0xffff, 0xc54d).is_none());
140 }
141}