usbd_human_interface_device/device/
mod.rs

1//! Concrete implementation of Human Interface Devices
2
3use crate::interface::InterfaceClass;
4use crate::UsbHidError;
5use frunk::{HCons, HNil, ToMut};
6#[allow(clippy::wildcard_imports)]
7use usb_device::class_prelude::*;
8use usb_device::descriptor::lang_id::LangID;
9
10pub mod consumer;
11pub mod fido;
12pub mod joystick;
13pub mod keyboard;
14pub mod mouse;
15pub mod multiaxis;
16
17pub trait DeviceClass<'a> {
18    type I: InterfaceClass<'a>;
19    fn interface(&mut self) -> &mut Self::I;
20    /// Called if the USB Device is reset
21    fn reset(&mut self);
22    /// Called every 1ms
23    fn tick(&mut self) -> Result<(), UsbHidError>;
24}
25
26pub trait DeviceHList<'a>: ToMut<'a> {
27    fn get(&mut self, id: u8) -> Option<&mut dyn InterfaceClass<'a>>;
28    fn reset(&mut self);
29    fn write_descriptors(&mut self, writer: &mut DescriptorWriter) -> usb_device::Result<()>;
30    fn get_string(&mut self, index: StringIndex, lang_id: LangID) -> Option<&'a str>;
31    fn tick(&mut self) -> Result<(), UsbHidError>;
32}
33
34impl<'a> DeviceHList<'a> for HNil {
35    fn get(&mut self, _: u8) -> Option<&mut dyn InterfaceClass<'a>> {
36        None
37    }
38
39    fn reset(&mut self) {}
40
41    fn write_descriptors(&mut self, _: &mut DescriptorWriter) -> usb_device::Result<()> {
42        Ok(())
43    }
44
45    fn get_string(&mut self, _: StringIndex, _: LangID) -> Option<&'a str> {
46        None
47    }
48
49    fn tick(&mut self) -> Result<(), UsbHidError> {
50        Ok(())
51    }
52}
53
54impl<'a, Head: DeviceClass<'a> + 'a, Tail: DeviceHList<'a>> DeviceHList<'a> for HCons<Head, Tail> {
55    fn get(&mut self, id: u8) -> Option<&mut dyn InterfaceClass<'a>> {
56        if id == u8::from(self.head.interface().id()) {
57            Some(self.head.interface())
58        } else {
59            self.tail.get(id)
60        }
61    }
62
63    fn reset(&mut self) {
64        self.head.interface().reset();
65        self.head.reset();
66        self.tail.reset();
67    }
68
69    fn write_descriptors(&mut self, writer: &mut DescriptorWriter) -> usb_device::Result<()> {
70        self.head.interface().write_descriptors(writer)?;
71        self.tail.write_descriptors(writer)
72    }
73
74    fn get_string(&mut self, index: StringIndex, lang_id: LangID) -> Option<&'a str> {
75        let s = self.head.interface().get_string(index, lang_id);
76        if s.is_some() {
77            s
78        } else {
79            self.tail.get_string(index, lang_id)
80        }
81    }
82
83    fn tick(&mut self) -> Result<(), UsbHidError> {
84        self.head.tick()?;
85        self.tail.tick()
86    }
87}