use super::types::{DpiDirection, Lod};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum ExtendedDpiEvent {
ParametersChanged(DpiParametersChanged),
CalibrationCompleted(DpiCalibrationCompleted),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub struct DpiParametersChanged {
pub sensor_index: u8,
pub dpi_x: u16,
pub dpi_y: u16,
pub lod: Lod,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub struct DpiCalibrationCompleted {
pub sensor_index: u8,
pub direction: DpiDirection,
pub correction: i16,
pub delta: i16,
}
impl DpiCalibrationCompleted {
#[must_use]
pub fn failed(&self) -> bool {
self.correction == i16::MIN
}
}
pub(super) fn decode_event(sub_id: u8, payload: &[u8; 16]) -> Option<ExtendedDpiEvent> {
match sub_id {
0 => Some(ExtendedDpiEvent::ParametersChanged(DpiParametersChanged {
sensor_index: payload[0],
dpi_x: u16::from_be_bytes([payload[1], payload[2]]),
dpi_y: u16::from_be_bytes([payload[3], payload[4]]),
lod: Lod::try_from(payload[5]).ok()?,
})),
1 => Some(ExtendedDpiEvent::CalibrationCompleted(
DpiCalibrationCompleted {
sensor_index: payload[0],
direction: DpiDirection::try_from(payload[1]).ok()?,
correction: i16::from_be_bytes([payload[2], payload[3]]),
delta: i16::from_be_bytes([payload[4], payload[5]]),
},
)),
_ => None,
}
}