use super::*;
#[cfg(feature = "serialize-json")]
use serde::{Deserialize, Serialize, Serializer};
use std::collections::{BTreeMap, HashMap};
pub type DeviceMessageAttributesMap = HashMap<ButtplugDeviceMessageType, DeviceMessageAttributes>;
fn ordered_map<S>(value: &DeviceMessageAttributesMap, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let ordered: BTreeMap<_, _> = value.iter().collect();
ordered.serialize(serializer)
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serialize-json", derive(Serialize, Deserialize))]
pub struct DeviceMessageInfo {
#[cfg_attr(feature = "serialize-json", serde(rename = "DeviceIndex"))]
pub device_index: u32,
#[cfg_attr(feature = "serialize-json", serde(rename = "DeviceName"))]
pub device_name: String,
#[cfg_attr(
feature = "serialize-json",
serde(rename = "DeviceMessages", serialize_with = "ordered_map")
)]
pub device_messages: DeviceMessageAttributesMap,
#[cfg_attr(feature = "serialize-json", serde(skip))]
pub original_device_messages: DeviceMessageAttributesMap,
}
impl DeviceMessageInfo {
pub fn new(
device_index: u32,
device_name: &str,
device_messages: DeviceMessageAttributesMap,
) -> Self {
Self {
device_index,
device_name: device_name.to_owned(),
device_messages: device_messages.to_owned(),
original_device_messages: device_messages,
}
}
}
impl From<DeviceAdded> for DeviceMessageInfo {
fn from(device_added: DeviceAdded) -> Self {
Self {
device_index: device_added.device_index(),
device_name: device_added.device_name().clone(),
device_messages: device_added.device_messages().clone(),
original_device_messages: device_added.device_messages().clone(),
}
}
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serialize-json", derive(Serialize, Deserialize))]
pub struct DeviceMessageInfoV1 {
#[cfg_attr(feature = "serialize-json", serde(rename = "DeviceIndex"))]
pub device_index: u32,
#[cfg_attr(feature = "serialize-json", serde(rename = "DeviceName"))]
pub device_name: String,
#[cfg_attr(
feature = "serialize-json",
serde(rename = "DeviceMessages", serialize_with = "ordered_map")
)]
pub device_messages: DeviceMessageAttributesMap,
}
impl From<DeviceAdded> for DeviceMessageInfoV1 {
fn from(device_added: DeviceAdded) -> Self {
let dmi = DeviceMessageInfo::from(device_added);
DeviceMessageInfoV1::from(dmi)
}
}
impl From<DeviceMessageInfo> for DeviceMessageInfoV1 {
fn from(device_message_info: DeviceMessageInfo) -> Self {
let mut dmi_v1 = Self {
device_index: device_message_info.device_index,
device_name: device_message_info.device_name,
device_messages: device_message_info.original_device_messages,
};
let v2_message_types = [
ButtplugDeviceMessageType::RawReadCmd,
ButtplugDeviceMessageType::RawWriteCmd,
ButtplugDeviceMessageType::RawSubscribeCmd,
ButtplugDeviceMessageType::RawUnsubscribeCmd,
ButtplugDeviceMessageType::BatteryLevelCmd,
ButtplugDeviceMessageType::RSSILevelCmd,
];
for t in &v2_message_types {
dmi_v1.device_messages.remove(t);
}
for attributes in &mut dmi_v1.device_messages.values_mut() {
*attributes = DeviceMessageAttributes {
feature_count: attributes.feature_count,
..Default::default()
};
}
if dmi_v1
.device_messages
.contains_key(&ButtplugDeviceMessageType::VibrateCmd)
{
dmi_v1.device_messages.insert(
ButtplugDeviceMessageType::SingleMotorVibrateCmd,
DeviceMessageAttributes::default(),
);
}
dmi_v1
}
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serialize-json", derive(Serialize, Deserialize))]
pub struct DeviceMessageInfoV0 {
#[cfg_attr(feature = "serialize-json", serde(rename = "DeviceIndex"))]
pub device_index: u32,
#[cfg_attr(feature = "serialize-json", serde(rename = "DeviceName"))]
pub device_name: String,
#[cfg_attr(feature = "serialize-json", serde(rename = "DeviceMessages"))]
pub device_messages: Vec<ButtplugDeviceMessageType>,
}
impl From<DeviceAdded> for DeviceMessageInfoV0 {
fn from(device_added: DeviceAdded) -> Self {
let dmi = DeviceMessageInfo::from(device_added);
let dmi_v1: DeviceMessageInfoV1 = dmi.into();
dmi_v1.into()
}
}
impl From<DeviceMessageInfoV1> for DeviceMessageInfoV0 {
fn from(device_message_info: DeviceMessageInfoV1) -> Self {
let mut device_messages: Vec<ButtplugDeviceMessageType> = device_message_info
.device_messages
.keys()
.cloned()
.collect();
let v1_message_types = [
ButtplugDeviceMessageType::VibrateCmd,
ButtplugDeviceMessageType::RotateCmd,
ButtplugDeviceMessageType::LinearCmd,
];
device_messages.retain(|x| !v1_message_types.contains(x));
device_messages.sort();
Self {
device_name: device_message_info.device_name,
device_index: device_message_info.device_index,
device_messages,
}
}
}