Buttplug sex toy control library
1// Buttplug Rust Source Code File - See https://buttplug.io for more info.
2//
3// Copyright 2016-2024 Nonpolynomial Labs LLC. All rights reserved.
4//
5// Licensed under the BSD 3-Clause license. See LICENSE file in the project root
6// for full license information.
7
8use crate::message::{
9 ServerDeviceAttributes,
10 TryFromDeviceAttributes,
11 checked_input_cmd::CheckedInputCmdV4,
12};
13use buttplug_core::{
14 errors::{ButtplugDeviceError, ButtplugError, ButtplugMessageError},
15 message::{
16 ButtplugDeviceMessage,
17 ButtplugMessage,
18 ButtplugMessageFinalizer,
19 ButtplugMessageValidator,
20 InputCommandType,
21 InputType,
22 },
23};
24use getset::{CopyGetters, Getters};
25use serde::{Deserialize, Serialize};
26
27#[derive(
28 Debug,
29 ButtplugDeviceMessage,
30 ButtplugMessageFinalizer,
31 PartialEq,
32 Eq,
33 Clone,
34 Getters,
35 CopyGetters,
36 Serialize,
37 Deserialize,
38)]
39pub struct SensorReadCmdV3 {
40 #[serde(rename = "Id")]
41 id: u32,
42 #[serde(rename = "DeviceIndex")]
43 device_index: u32,
44 #[getset(get = "pub")]
45 #[serde(rename = "SensorIndex")]
46 sensor_index: u32,
47 #[getset(get = "pub")]
48 #[serde(rename = "SensorType")]
49 sensor_type: InputType,
50}
51
52impl SensorReadCmdV3 {
53 pub fn new(device_index: u32, sensor_index: u32, sensor_type: InputType) -> Self {
54 Self {
55 id: 1,
56 device_index,
57 sensor_index,
58 sensor_type,
59 }
60 }
61}
62
63impl ButtplugMessageValidator for SensorReadCmdV3 {
64 fn is_valid(&self) -> Result<(), ButtplugMessageError> {
65 self.is_not_system_id(self.id)
66 // TODO Should expected_length always be > 0?
67 }
68}
69
70impl TryFromDeviceAttributes<SensorReadCmdV3> for CheckedInputCmdV4 {
71 fn try_from_device_attributes(
72 msg: SensorReadCmdV3,
73 features: &ServerDeviceAttributes,
74 ) -> Result<Self, buttplug_core::errors::ButtplugError> {
75 // Reject any SensorRead that's not a battery, we never supported sensors otherwise in v3.
76 if msg.sensor_type != InputType::Battery {
77 Err(ButtplugError::from(
78 ButtplugDeviceError::MessageNotSupported("SensorReadCmdV3".to_owned()),
79 ))
80 } else if let Some((feature_index, feature)) = features
81 .features()
82 .iter()
83 .enumerate()
84 .find(|(_, p)| p.input().as_ref().is_some_and(|x| x.battery().is_some()))
85 {
86 Ok(CheckedInputCmdV4::new(
87 msg.device_index(),
88 feature_index as u32,
89 InputType::Battery,
90 InputCommandType::Read,
91 feature.id(),
92 ))
93 } else {
94 Err(ButtplugError::from(
95 ButtplugDeviceError::MessageNotSupported("SensorReadCmdV3".to_owned()),
96 ))
97 }
98 }
99}