use num_enum::{IntoPrimitive, TryFromPrimitive};
use openlogi_hidpp_derive::Feature;
use crate::{
feature::{DecodeEvent, EventSource, FeatureEndpoint},
protocol::v20::Hidpp20Error,
};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum DualPlatformSelection {
IosOrMac = 0,
AndroidOrWindows = 1,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum DualPlatformEvent {
PlatformChanged(DualPlatformSelection),
}
#[derive(Feature)]
#[creatable(id = 0x4530, version = 0)]
pub struct DualPlatformFeature {
endpoint: FeatureEndpoint,
events: EventSource<DualPlatformEvent>,
}
impl DecodeEvent for DualPlatformEvent {
fn decode(sub_id: u8, payload: &[u8; 16]) -> Option<Self> {
if sub_id != 0 {
return None;
}
DualPlatformSelection::try_from(payload[0])
.ok()
.map(DualPlatformEvent::PlatformChanged)
}
}
impl DualPlatformFeature {
pub async fn get_platform(&self) -> Result<DualPlatformSelection, Hidpp20Error> {
let payload = self.endpoint.call(1, [0; 3]).await?.extend_payload();
DualPlatformSelection::try_from(payload[0]).map_err(|_| Hidpp20Error::UnsupportedResponse)
}
pub async fn set_platform(
&self,
platform: DualPlatformSelection,
) -> Result<DualPlatformSelection, Hidpp20Error> {
let payload = self
.endpoint
.call(2, [platform.into(), 0, 0])
.await?
.extend_payload();
DualPlatformSelection::try_from(payload[0]).map_err(|_| Hidpp20Error::UnsupportedResponse)
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used, reason = "expect/unwrap are idiomatic in tests")]
mod tests {
use super::DualPlatformSelection;
#[test]
fn maps_platform_wire_values() {
assert_eq!(
DualPlatformSelection::try_from(0).unwrap(),
DualPlatformSelection::IosOrMac
);
assert_eq!(
DualPlatformSelection::try_from(1).unwrap(),
DualPlatformSelection::AndroidOrWindows
);
DualPlatformSelection::try_from(2).unwrap_err();
assert_eq!(u8::from(DualPlatformSelection::AndroidOrWindows), 1);
}
}