use hidpp::feature::device_type_and_name::DeviceType as HidppDeviceType;
use hidpp::feature::unified_battery::{
BatteryLevel as HidppBatteryLevel, BatteryStatus as HidppBatteryStatus,
};
use hidpp::receiver::bolt::DeviceKind as BoltDeviceKind;
use hidpp::receiver::unifying::DeviceKind as UnifyingDeviceKind;
use openlogi_core::device::{BatteryLevel, BatteryStatus, DeviceKind};
pub(crate) fn normalize_serial_number(serial: &str) -> Option<String> {
let serial = serial.trim_matches('\0').trim().to_string();
(!serial.is_empty()).then_some(serial)
}
pub(crate) fn map_kind(k: BoltDeviceKind) -> DeviceKind {
match k {
BoltDeviceKind::Keyboard => DeviceKind::Keyboard,
BoltDeviceKind::Mouse => DeviceKind::Mouse,
BoltDeviceKind::Numpad => DeviceKind::Numpad,
BoltDeviceKind::Presenter => DeviceKind::Presenter,
BoltDeviceKind::Remote => DeviceKind::Remote,
BoltDeviceKind::Trackball => DeviceKind::Trackball,
BoltDeviceKind::Touchpad => DeviceKind::Touchpad,
BoltDeviceKind::Tablet => DeviceKind::Tablet,
BoltDeviceKind::Gamepad => DeviceKind::Gamepad,
BoltDeviceKind::Joystick => DeviceKind::Joystick,
BoltDeviceKind::Headset => DeviceKind::Headset,
_ => DeviceKind::Unknown,
}
}
pub(crate) fn map_unifying_kind(k: UnifyingDeviceKind) -> DeviceKind {
match k {
UnifyingDeviceKind::Keyboard => DeviceKind::Keyboard,
UnifyingDeviceKind::Mouse => DeviceKind::Mouse,
UnifyingDeviceKind::Numpad => DeviceKind::Numpad,
UnifyingDeviceKind::Presenter => DeviceKind::Presenter,
UnifyingDeviceKind::Remote => DeviceKind::Remote,
UnifyingDeviceKind::Trackball => DeviceKind::Trackball,
UnifyingDeviceKind::Touchpad => DeviceKind::Touchpad,
_ => DeviceKind::Unknown,
}
}
pub(crate) fn map_device_type(ty: HidppDeviceType) -> DeviceKind {
match ty {
HidppDeviceType::Keyboard => DeviceKind::Keyboard,
HidppDeviceType::Numpad => DeviceKind::Numpad,
HidppDeviceType::Mouse => DeviceKind::Mouse,
HidppDeviceType::Trackpad => DeviceKind::Touchpad,
HidppDeviceType::Trackball => DeviceKind::Trackball,
HidppDeviceType::Presenter => DeviceKind::Presenter,
HidppDeviceType::RemoteControl => DeviceKind::Remote,
HidppDeviceType::Headset => DeviceKind::Headset,
HidppDeviceType::Joystick => DeviceKind::Joystick,
HidppDeviceType::Gamepad => DeviceKind::Gamepad,
_ => DeviceKind::Unknown,
}
}
pub(crate) fn resolve_device_kind(probed: Option<DeviceKind>, register: DeviceKind) -> DeviceKind {
match probed {
Some(kind) if kind != DeviceKind::Unknown => kind,
_ => register,
}
}
pub(crate) fn map_battery_level(level: HidppBatteryLevel) -> BatteryLevel {
match level {
HidppBatteryLevel::Critical => BatteryLevel::Critical,
HidppBatteryLevel::Low => BatteryLevel::Low,
HidppBatteryLevel::Good => BatteryLevel::Good,
HidppBatteryLevel::Full => BatteryLevel::Full,
_ => BatteryLevel::Unknown,
}
}
pub(crate) fn map_battery_status(status: HidppBatteryStatus) -> BatteryStatus {
match status {
HidppBatteryStatus::Discharging => BatteryStatus::Discharging,
HidppBatteryStatus::Charging => BatteryStatus::Charging,
HidppBatteryStatus::ChargingSlow => BatteryStatus::ChargingSlow,
HidppBatteryStatus::Full => BatteryStatus::Full,
HidppBatteryStatus::Error => BatteryStatus::Error,
_ => BatteryStatus::Unknown,
}
}
#[cfg(test)]
mod tests {
use super::{DeviceKind, UnifyingDeviceKind, map_unifying_kind, resolve_device_kind};
#[test]
fn probe_overrides_a_misreporting_register() {
assert_eq!(
resolve_device_kind(Some(DeviceKind::Mouse), DeviceKind::Keyboard),
DeviceKind::Mouse
);
}
#[test]
fn probe_supplies_the_kind_on_the_direct_path() {
assert_eq!(
resolve_device_kind(Some(DeviceKind::Mouse), DeviceKind::Unknown),
DeviceKind::Mouse
);
}
#[test]
fn register_is_the_fallback_when_the_probe_is_absent_or_unmodelled() {
assert_eq!(
resolve_device_kind(None, DeviceKind::Mouse),
DeviceKind::Mouse
);
assert_eq!(
resolve_device_kind(Some(DeviceKind::Unknown), DeviceKind::Keyboard),
DeviceKind::Keyboard
);
assert_eq!(
resolve_device_kind(None, DeviceKind::Unknown),
DeviceKind::Unknown
);
}
#[test]
fn unifying_kind_maps_all_variants() {
let cases = [
(UnifyingDeviceKind::Unknown, DeviceKind::Unknown),
(UnifyingDeviceKind::Keyboard, DeviceKind::Keyboard),
(UnifyingDeviceKind::Mouse, DeviceKind::Mouse),
(UnifyingDeviceKind::Numpad, DeviceKind::Numpad),
(UnifyingDeviceKind::Presenter, DeviceKind::Presenter),
(UnifyingDeviceKind::Remote, DeviceKind::Remote),
(UnifyingDeviceKind::Trackball, DeviceKind::Trackball),
(UnifyingDeviceKind::Touchpad, DeviceKind::Touchpad),
];
for (input, expected) in cases {
assert_eq!(
map_unifying_kind(input),
expected,
"kind {input:?} mapped incorrectly"
);
}
}
}