use num_enum::{FromPrimitive, IntoPrimitive};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, FromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum RotationState {
Inactive = 0,
Start = 1,
Active = 2,
Stop = 3,
#[num_enum(catch_all)]
Other(u8),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, FromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum ActivityState {
Inactive = 0,
Start = 1,
Active = 2,
Stop = 3,
#[num_enum(catch_all)]
Other(u8),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, FromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum CrownGesture {
None = 0,
Tap = 1,
DoubleTap = 2,
#[num_enum(catch_all)]
Other(u8),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, FromPrimitive)]
#[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,
#[num_enum(catch_all)]
Other(u8),
}
#[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::from(payload[0]),
relative_slot_rotation: payload[1] as i8,
relative_ratchet_rotation: payload[2] as i8,
proximity: ActivityState::from(payload[3]),
touch: ActivityState::from(payload[4]),
gesture: CrownGesture::from(payload[5]),
button: ButtonState::from(payload[6]),
speed: i16::from_be_bytes([payload[14], payload[15]]),
})),
_ => None,
}
}