1#![forbid(future_incompatible)]
2#![deny(bad_style, missing_docs)]
3#![doc = include_str!("../README.md")]
4
5#[cfg(not(target_os = "linux"))]
6compile_error!("This crate support Linux only");
7
8#[cfg(feature = "serde")]
9use serde::{Deserialize, Serialize};
10
11#[macro_use]
12mod macros;
13
14#[cfg(feature = "either")]
15mod either_report;
16
17#[cfg(feature = "keyboard")]
18mod keyboard;
19
20#[cfg(feature = "mouse")]
21mod mouse;
22
23#[cfg(feature = "keyboard")]
24pub use keyboard::{
25 Key, KeyStateChanges, Keyboard, KeyboardInput, KeyboardOutput, Led, LedStateChanges, Leds,
26 Modifiers,
27};
28
29#[cfg(feature = "mouse")]
30pub use mouse::{
31 Button, Buttons, Mouse, MouseInput, MouseInputChange, MouseInputChanges, MouseOutput,
32};
33
34use std::{
35 io::ErrorKind,
36 path::{Path, PathBuf},
37};
38
39pub use std::io::{Error, Result};
40
41#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
43pub struct Unknown;
44
45impl std::error::Error for Unknown {}
46
47impl core::fmt::Display for Unknown {
48 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
49 f.write_str("Unknown")
50 }
51}
52
53#[derive(Clone, Copy, Debug, PartialEq, Eq)]
55#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
56pub struct StateChange<T> {
57 data: T,
58 state: bool,
59}
60
61impl<T> StateChange<T> {
62 pub fn new(data: T, state: bool) -> Self {
64 Self { data, state }
65 }
66
67 pub fn press(data: T) -> Self {
69 Self::new(data, true)
70 }
71
72 pub fn on(data: T) -> Self {
74 Self::new(data, true)
75 }
76
77 pub fn release(data: T) -> Self {
79 Self::new(data, false)
80 }
81
82 pub fn off(data: T) -> Self {
84 Self::new(data, false)
85 }
86
87 pub fn data(&self) -> T
89 where
90 T: Copy,
91 {
92 self.data
93 }
94
95 pub fn state(&self) -> bool {
97 self.state
98 }
99
100 pub fn is_press(&self) -> bool {
102 self.state
103 }
104
105 pub fn is_on(&self) -> bool {
107 self.state
108 }
109
110 pub fn is_release(&self) -> bool {
112 !self.state
113 }
114
115 pub fn is_off(&self) -> bool {
117 !self.state
118 }
119}
120
121impl<T> From<(T, bool)> for StateChange<T> {
122 fn from((data, state): (T, bool)) -> Self {
123 Self { data, state }
124 }
125}
126
127impl<T> From<StateChange<T>> for (T, bool) {
128 fn from(StateChange { data, state }: StateChange<T>) -> Self {
129 (data, state)
130 }
131}
132
133#[derive(Clone, Copy, Debug, PartialEq, Eq)]
135#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
136pub struct ValueChange<T> {
137 data: T,
138 #[cfg_attr(feature = "serde", serde(rename = "rel"))]
139 relative: bool,
140}
141
142impl<T> ValueChange<T> {
143 pub fn new(data: T, relative: bool) -> Self {
145 Self { data, relative }
146 }
147
148 pub fn data(&self) -> T
150 where
151 T: Copy,
152 {
153 self.data
154 }
155
156 pub fn absolute(data: T) -> Self {
158 Self::new(data, false)
159 }
160
161 pub fn relative(data: T) -> Self {
163 Self::new(data, true)
164 }
165
166 pub fn is_relative(&self) -> bool {
168 self.relative
169 }
170
171 pub fn is_absolute(&self) -> bool {
173 !self.relative
174 }
175}
176
177impl<T> From<(T, bool)> for ValueChange<T> {
178 fn from((data, relative): (T, bool)) -> Self {
179 Self { data, relative }
180 }
181}
182
183impl<T> From<ValueChange<T>> for (T, bool) {
184 fn from(ValueChange { data, relative }: ValueChange<T>) -> Self {
185 (data, relative)
186 }
187}
188
189deref_impl! {
190 StateChange<T> => data: T,
191 ValueChange<T> => data: T,
192}
193
194pub trait Class {
196 type Input;
198
199 type Output;
201
202 fn input(&self) -> Self::Input;
204
205 fn output(&self) -> Self::Output;
207}
208
209pub trait AsDevicePath {
211 fn as_device_path(&self) -> PathBuf;
213}
214
215impl AsDevicePath for Path {
216 fn as_device_path(&self) -> PathBuf {
217 if self.is_absolute() {
218 self.to_path_buf()
219 } else {
220 Path::new("/dev").join(self)
221 }
222 }
223}
224
225impl AsDevicePath for &Path {
226 fn as_device_path(&self) -> PathBuf {
227 if self.is_absolute() {
228 self.to_path_buf()
229 } else {
230 Path::new("/dev").join(self)
231 }
232 }
233}
234
235impl AsDevicePath for PathBuf {
236 fn as_device_path(&self) -> PathBuf {
237 let path: &Path = self;
238 path.as_device_path()
239 }
240}
241
242impl AsDevicePath for &PathBuf {
243 fn as_device_path(&self) -> PathBuf {
244 let path: &Path = self;
245 path.as_device_path()
246 }
247}
248
249impl AsDevicePath for &str {
250 fn as_device_path(&self) -> PathBuf {
251 Path::new(self).as_device_path()
252 }
253}
254
255impl AsDevicePath for String {
256 fn as_device_path(&self) -> PathBuf {
257 let s: &str = self;
258 s.as_device_path()
259 }
260}
261
262impl AsDevicePath for &String {
263 fn as_device_path(&self) -> PathBuf {
264 let s: &str = self;
265 s.as_device_path()
266 }
267}
268
269impl AsDevicePath for usize {
270 fn as_device_path(&self) -> PathBuf {
271 format!("/dev/hidg{self}").as_device_path()
272 }
273}
274
275macro_rules! as_device_path {
276 ($($type:ty),*) => {
277 $(
278 impl AsDevicePath for $type {
279 fn as_device_path(&self) -> PathBuf {
280 (*self as usize).as_device_path()
281 }
282 }
283 )*
284 };
285}
286
287as_device_path!(u8, u16, u32, u64, i8, i16, i32, i64, isize);
288
289#[derive(Clone, Copy, Default)]
291pub struct Internal<T>(T);
292
293impl<T> core::ops::Deref for Internal<T> {
294 type Target = T;
295
296 fn deref(&self) -> &Self::Target {
297 &self.0
298 }
299}
300
301impl<T> core::ops::DerefMut for Internal<T> {
302 fn deref_mut(&mut self) -> &mut Self::Target {
303 &mut self.0
304 }
305}
306
307pub fn check_write(actual: usize, expected: usize) -> Result<()> {
309 if actual == expected {
310 Ok(())
311 } else {
312 Err(Error::new(ErrorKind::Other, "Error when writing report"))
313 }
314}
315
316pub fn check_read(actual: usize, expected: usize) -> Result<()> {
318 if actual == expected {
319 Ok(())
320 } else {
321 Err(Error::new(ErrorKind::Other, "Error when reading report"))
322 }
323}