use core::ffi::c_char;
use std::fmt;
use bitflags::bitflags;
use cue_sdk_sys as ffi;
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct DeviceId(pub(crate) ffi::CorsairDeviceId);
impl DeviceId {
pub(crate) fn as_ptr(&self) -> *const c_char {
self.0.as_ptr()
}
pub(crate) fn from_ffi(raw: ffi::CorsairDeviceId) -> Self {
Self(raw)
}
}
impl fmt::Debug for DeviceId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "DeviceId(\"{}\")", self)
}
}
impl fmt::Display for DeviceId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let bytes = self.0.map(|c| c as u8);
let len = bytes.iter().position(|&b| b == 0).unwrap_or(bytes.len());
let s = std::str::from_utf8(&bytes[..len]).unwrap_or("<invalid utf8>");
f.write_str(s)
}
}
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct DeviceType: u32 {
const UNKNOWN = ffi::CorsairDeviceType_CDT_Unknown;
const KEYBOARD = ffi::CorsairDeviceType_CDT_Keyboard;
const MOUSE = ffi::CorsairDeviceType_CDT_Mouse;
const MOUSEMAT = ffi::CorsairDeviceType_CDT_Mousemat;
const HEADSET = ffi::CorsairDeviceType_CDT_Headset;
const HEADSET_STAND = ffi::CorsairDeviceType_CDT_HeadsetStand;
const FAN_LED_CONTROLLER = ffi::CorsairDeviceType_CDT_FanLedController;
const LED_CONTROLLER = ffi::CorsairDeviceType_CDT_LedController;
const MEMORY_MODULE = ffi::CorsairDeviceType_CDT_MemoryModule;
const COOLER = ffi::CorsairDeviceType_CDT_Cooler;
const MOTHERBOARD = ffi::CorsairDeviceType_CDT_Motherboard;
const GRAPHICS_CARD = ffi::CorsairDeviceType_CDT_GraphicsCard;
const TOUCHBAR = ffi::CorsairDeviceType_CDT_Touchbar;
const GAME_CONTROLLER = ffi::CorsairDeviceType_CDT_GameController;
const ALL = ffi::CorsairDeviceType_CDT_All;
}
}
#[derive(Debug, Clone)]
pub struct DeviceInfo {
pub device_type: DeviceType,
pub id: DeviceId,
pub serial: String,
pub model: String,
pub led_count: i32,
pub channel_count: i32,
}
impl DeviceInfo {
pub(crate) fn from_ffi(raw: &ffi::CorsairDeviceInfo) -> Self {
Self {
device_type: DeviceType::from_bits_truncate(raw.type_),
id: DeviceId::from_ffi(raw.id),
serial: c_char_array_to_string(&raw.serial),
model: c_char_array_to_string(&raw.model),
led_count: raw.ledCount,
channel_count: raw.channelCount,
}
}
}
fn c_char_array_to_string(arr: &[c_char]) -> String {
let bytes: Vec<u8> = arr
.iter()
.map(|&c| c as u8)
.take_while(|&b| b != 0)
.collect();
String::from_utf8_lossy(&bytes).into_owned()
}