use num_enum::{IntoPrimitive, TryFromPrimitive};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum RotationState {
Inactive = 0,
Start = 1,
Active = 2,
Stop = 3,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum ActivityState {
Inactive = 0,
Start = 1,
Active = 2,
Stop = 3,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum CrownGesture {
None = 0,
Tap = 1,
DoubleTap = 2,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum ButtonState {
Inactive = 0,
Press = 1,
ShortPressActive = 2,
LongPress = 3,
LongPressActive = 4,
Release = 5,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum CrownEvent {
Update(CrownUpdate),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub struct CrownUpdate {
pub rotation_state: RotationState,
pub relative_slot_rotation: i8,
pub relative_ratchet_rotation: i8,
pub proximity: ActivityState,
pub touch: ActivityState,
pub gesture: CrownGesture,
pub button: ButtonState,
pub speed: i16,
}
pub(super) fn decode_event(sub_id: u8, payload: &[u8; 16]) -> Option<CrownEvent> {
match sub_id {
0 => Some(CrownEvent::Update(CrownUpdate {
rotation_state: RotationState::try_from(payload[0]).ok()?,
relative_slot_rotation: payload[1] as i8,
relative_ratchet_rotation: payload[2] as i8,
proximity: ActivityState::try_from(payload[3]).ok()?,
touch: ActivityState::try_from(payload[4]).ok()?,
gesture: CrownGesture::try_from(payload[5]).ok()?,
button: ButtonState::try_from(payload[6]).ok()?,
speed: i16::from_be_bytes([payload[14], payload[15]]),
})),
_ => None,
}
}