openlogi_hid/write/
error.rs1use hidpp::protocol::v20::{ErrorType, Hidpp20Error};
2use serde::{Deserialize, Serialize};
3use thiserror::Error;
4
5#[derive(Debug, Clone, Error, Serialize, Deserialize)]
15pub enum WriteError {
16 #[error("HID transport error: {0}")]
21 Hid(String),
22 #[error("no connected device matched the route")]
24 DeviceNotFound,
25 #[error("device at index {index:#04x} did not respond to HID++")]
27 DeviceUnreachable {
28 index: u8,
30 },
31 #[error("device does not expose HID++ feature {feature_hex:#06x}")]
33 FeatureUnsupported {
34 feature_hex: u16,
36 },
37 #[error("device returned no supported DPI values")]
39 EmptyDpiList,
40 #[error("HID++ protocol error: {0}")]
42 Hidpp(String),
43 #[error("HID++ feature error during {operation:?} for feature {feature_hex:#06x}: {kind:?}")]
45 HidppFeature {
46 operation: HidppOperation,
48 feature_hex: u16,
50 kind: HidppFeatureErrorKind,
52 },
53 #[error("HID++ unsupported response during {operation:?} for feature {feature_hex:#06x}")]
55 UnsupportedResponse {
56 operation: HidppOperation,
58 feature_hex: u16,
60 },
61 #[error("HID++ request timed out during {operation:?}")]
63 RequestTimedOut {
64 operation: HidppOperation,
66 },
67 #[error("tokio runtime init failed: {message}")]
69 RuntimeInit {
70 message: String,
72 },
73 #[error("background agent is unavailable")]
75 AgentUnavailable,
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
82pub enum HidppOperation {
83 ResolveFeature,
85 DumpFeatures,
87 ReadDpi,
89 ReadDpiCapabilities,
91 WriteDpi,
93 ReadSmartShift,
95 WriteSmartShift,
97 Lighting,
99 ReadWheelMode,
101 WriteWheelMode,
103}
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
109pub enum HidppFeatureErrorKind {
110 NoError,
112 Unknown,
114 InvalidArgument,
116 OutOfRange,
118 HwError,
120 LogitechInternal,
122 InvalidFeatureIndex,
124 InvalidFunctionId,
126 Busy,
128 Unsupported,
130 Unrecognized,
132}
133
134impl From<async_hid::HidError> for WriteError {
135 fn from(e: async_hid::HidError) -> Self {
136 Self::Hid(e.to_string())
137 }
138}
139
140fn hidpp_feature_error_kind(kind: ErrorType) -> HidppFeatureErrorKind {
141 match kind {
142 ErrorType::NoError => HidppFeatureErrorKind::NoError,
143 ErrorType::Unknown => HidppFeatureErrorKind::Unknown,
144 ErrorType::InvalidArgument => HidppFeatureErrorKind::InvalidArgument,
145 ErrorType::OutOfRange => HidppFeatureErrorKind::OutOfRange,
146 ErrorType::HwError => HidppFeatureErrorKind::HwError,
147 ErrorType::LogitechInternal => HidppFeatureErrorKind::LogitechInternal,
148 ErrorType::InvalidFeatureIndex => HidppFeatureErrorKind::InvalidFeatureIndex,
149 ErrorType::InvalidFunctionId => HidppFeatureErrorKind::InvalidFunctionId,
150 ErrorType::Busy => HidppFeatureErrorKind::Busy,
151 ErrorType::Unsupported => HidppFeatureErrorKind::Unsupported,
152 _ => HidppFeatureErrorKind::Unrecognized,
153 }
154}
155
156pub(crate) fn classify_hidpp_error(
157 error: Hidpp20Error,
158 operation: HidppOperation,
159 feature_hex: u16,
160) -> WriteError {
161 match error {
162 Hidpp20Error::Feature(kind) => WriteError::HidppFeature {
163 operation,
164 feature_hex,
165 kind: hidpp_feature_error_kind(kind),
166 },
167 Hidpp20Error::UnsupportedResponse => WriteError::UnsupportedResponse {
168 operation,
169 feature_hex,
170 },
171 Hidpp20Error::Channel(error) => WriteError::Hidpp(format!("{error:?}")),
172 _ => WriteError::Hidpp(format!("{error:?}")),
173 }
174}