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 serde::{Deserialize, Serialize};
25
26/// Battery level request
27#[derive(
28 Debug,
29 ButtplugDeviceMessage,
30 ButtplugMessageFinalizer,
31 PartialEq,
32 Eq,
33 Clone,
34 Serialize,
35 Deserialize,
36)]
37pub struct BatteryLevelCmdV2 {
38 #[serde(rename = "Id")]
39 id: u32,
40 #[serde(rename = "DeviceIndex")]
41 device_index: u32,
42}
43
44impl BatteryLevelCmdV2 {
45 pub fn new(device_index: u32) -> Self {
46 Self {
47 id: 1,
48 device_index,
49 }
50 }
51}
52
53impl ButtplugMessageValidator for BatteryLevelCmdV2 {
54 fn is_valid(&self) -> Result<(), ButtplugMessageError> {
55 self.is_not_system_id(self.id)
56 }
57}
58
59impl TryFromDeviceAttributes<BatteryLevelCmdV2> for CheckedInputCmdV4 {
60 fn try_from_device_attributes(
61 msg: BatteryLevelCmdV2,
62 features: &ServerDeviceAttributes,
63 ) -> Result<Self, buttplug_core::errors::ButtplugError> {
64 let battery_feature = features
65 .attrs_v2()
66 .battery_level_cmd()
67 .as_ref()
68 .ok_or(ButtplugError::from(
69 ButtplugDeviceError::DeviceConfigurationError(
70 "Device configuration does not have Battery sensor available.".to_owned(),
71 ),
72 ))?
73 .feature();
74
75 let feature_index = features
76 .features()
77 .iter()
78 .enumerate()
79 .find(|(_, p)| p.input().as_ref().is_some_and(|x| x.battery().is_some()))
80 .expect("Already found matching battery feature, can unwrap this.")
81 .0;
82
83 Ok(CheckedInputCmdV4::new(
84 msg.device_index(),
85 feature_index as u32,
86 InputType::Battery,
87 InputCommandType::Read,
88 battery_feature.id(),
89 ))
90 }
91}