1use std::borrow::Cow;
2use std::fmt::{Debug, Display, Formatter};
3use std::panic::Location;
4
5pub type HidResult<T> = Result<T, HidError>;
7
8#[derive(Debug)]
11pub enum HidError {
12 Message(Cow<'static, str>),
13 Other(Box<dyn std::error::Error + Send + Sync>)
14}
15
16impl HidError {
17 pub fn message(msg: impl Into<Cow<'static, str>>) -> Self {
18 Self::Message(msg.into())
19 }
20
21 #[track_caller]
22 pub fn from_backend(error: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> Self {
23 let error = error.into();
24 log::trace!("Backend error: {} at {}", error, Location::caller());
25 Self::Other(error)
26 }
27}
28
29impl Display for HidError {
30 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
31 match self {
32 HidError::Message(msg) => f.write_str(msg),
33 HidError::Other(err) => Display::fmt(err, f)
34 }
35 }
36}
37
38impl std::error::Error for HidError {
39 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
40 match self {
41 HidError::Other(err) => Some(err.as_ref()),
42 _ => None
43 }
44 }
45}
46
47impl From<std::io::Error> for HidError {
48 #[track_caller]
49 fn from(value: std::io::Error) -> Self {
50 HidError::from_backend(value)
51 }
52}
53
54#[cfg(target_os = "windows")]
55impl From<windows::core::Error> for HidError {
56 #[track_caller]
57 fn from(error: windows::core::Error) -> Self {
58 HidError::from_backend(error)
59 }
60}
61
62#[doc(hidden)]
63#[macro_export]
64macro_rules! ensure {
65 ($cond:expr, $result:expr) => {
66 if !($cond) {
67 return Err($result);
68 }
69 };
70 ($cond:expr) => {
71 if !($cond) {
72 return None;
73 }
74 };
75}