Buttplug sex toy control library
at master 201 lines 6.8 kB view raw
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 v1::{LinearCmdV1, RequestServerInfoV1, RotateCmdV1, VibrateCmdV1}, 10 v2::{ButtplugClientMessageV2, ButtplugServerMessageV2, ServerInfoV2}, 11}; 12use buttplug_core::{ 13 errors::{ButtplugError, ButtplugMessageError}, 14 message::{ 15 ButtplugMessage, 16 ButtplugMessageFinalizer, 17 ButtplugMessageValidator, 18 ButtplugServerMessageV4, 19 DeviceRemovedV0, 20 ErrorV0, 21 OkV0, 22 PingV0, 23 RequestDeviceListV0, 24 ScanningFinishedV0, 25 StartScanningV0, 26 StopAllDevicesV0, 27 StopDeviceCmdV0, 28 StopScanningV0, 29 }, 30}; 31use serde::{Deserialize, Serialize}; 32 33use super::{ 34 DeviceAddedV3, 35 DeviceListV3, 36 ScalarCmdV3, 37 SensorReadCmdV3, 38 SensorReadingV3, 39 SensorSubscribeCmdV3, 40 SensorUnsubscribeCmdV3, 41}; 42 43/// Represents all client-to-server messages in v3 of the Buttplug Spec 44#[derive( 45 Debug, 46 Clone, 47 PartialEq, 48 ButtplugMessage, 49 ButtplugMessageValidator, 50 ButtplugMessageFinalizer, 51 FromSpecificButtplugMessage, 52 Serialize, 53 Deserialize, 54)] 55pub enum ButtplugClientMessageV3 { 56 // Handshake messages 57 RequestServerInfo(RequestServerInfoV1), 58 Ping(PingV0), 59 // Device enumeration messages 60 StartScanning(StartScanningV0), 61 StopScanning(StopScanningV0), 62 RequestDeviceList(RequestDeviceListV0), 63 // Generic commands 64 StopAllDevices(StopAllDevicesV0), 65 VibrateCmd(VibrateCmdV1), 66 LinearCmd(LinearCmdV1), 67 RotateCmd(RotateCmdV1), 68 StopDeviceCmd(StopDeviceCmdV0), 69 ScalarCmd(ScalarCmdV3), 70 // Sensor commands 71 SensorReadCmd(SensorReadCmdV3), 72 SensorSubscribeCmd(SensorSubscribeCmdV3), 73 SensorUnsubscribeCmd(SensorUnsubscribeCmdV3), 74} 75 76// For v2 to v3, all deprecations should be treated as conversions, but will require current 77// connected device state, meaning they'll need to be implemented where they can also access the 78// device manager. 79impl TryFrom<ButtplugClientMessageV2> for ButtplugClientMessageV3 { 80 type Error = ButtplugMessageError; 81 82 fn try_from(value: ButtplugClientMessageV2) -> Result<Self, Self::Error> { 83 match value { 84 ButtplugClientMessageV2::Ping(m) => Ok(ButtplugClientMessageV3::Ping(m.clone())), 85 ButtplugClientMessageV2::RequestServerInfo(m) => { 86 Ok(ButtplugClientMessageV3::RequestServerInfo(m.clone())) 87 } 88 ButtplugClientMessageV2::StartScanning(m) => { 89 Ok(ButtplugClientMessageV3::StartScanning(m.clone())) 90 } 91 ButtplugClientMessageV2::StopScanning(m) => { 92 Ok(ButtplugClientMessageV3::StopScanning(m.clone())) 93 } 94 ButtplugClientMessageV2::RequestDeviceList(m) => { 95 Ok(ButtplugClientMessageV3::RequestDeviceList(m.clone())) 96 } 97 ButtplugClientMessageV2::StopAllDevices(m) => { 98 Ok(ButtplugClientMessageV3::StopAllDevices(m.clone())) 99 } 100 ButtplugClientMessageV2::StopDeviceCmd(m) => { 101 Ok(ButtplugClientMessageV3::StopDeviceCmd(m.clone())) 102 } 103 // Vibrate was supposed to be phased out in v3 but was left in the allowable message set. 104 // Oops. 105 ButtplugClientMessageV2::VibrateCmd(m) => Ok(ButtplugClientMessageV3::VibrateCmd(m)), 106 ButtplugClientMessageV2::LinearCmd(m) => Ok(ButtplugClientMessageV3::LinearCmd(m)), 107 ButtplugClientMessageV2::RotateCmd(m) => Ok(ButtplugClientMessageV3::RotateCmd(m)), 108 _ => Err(ButtplugMessageError::MessageConversionError(format!( 109 "Cannot convert message {value:?} to V3 message spec while lacking state." 110 ))), 111 } 112 } 113} 114 115/// Represents all server-to-client messages in v3 of the Buttplug Spec 116#[derive( 117 Debug, 118 Clone, 119 ButtplugMessage, 120 ButtplugMessageValidator, 121 FromSpecificButtplugMessage, 122 Serialize, 123 Deserialize, 124)] 125pub enum ButtplugServerMessageV3 { 126 // Status messages 127 Ok(OkV0), 128 Error(ErrorV0), 129 // Handshake messages 130 ServerInfo(ServerInfoV2), 131 // Device enumeration messages 132 DeviceList(DeviceListV3), 133 DeviceAdded(DeviceAddedV3), 134 DeviceRemoved(DeviceRemovedV0), 135 ScanningFinished(ScanningFinishedV0), 136 // Sensor commands 137 SensorReading(SensorReadingV3), 138} 139 140impl ButtplugMessageFinalizer for ButtplugServerMessageV3 { 141 fn finalize(&mut self) { 142 match self { 143 ButtplugServerMessageV3::DeviceAdded(da) => da.finalize(), 144 ButtplugServerMessageV3::DeviceList(dl) => dl.finalize(), 145 _ => (), 146 } 147 } 148} 149 150impl From<ButtplugServerMessageV3> for ButtplugServerMessageV2 { 151 fn from(value: ButtplugServerMessageV3) -> Self { 152 match value { 153 ButtplugServerMessageV3::Ok(m) => ButtplugServerMessageV2::Ok(m), 154 ButtplugServerMessageV3::Error(m) => ButtplugServerMessageV2::Error(m), 155 ButtplugServerMessageV3::ServerInfo(m) => ButtplugServerMessageV2::ServerInfo(m), 156 ButtplugServerMessageV3::DeviceRemoved(m) => ButtplugServerMessageV2::DeviceRemoved(m), 157 ButtplugServerMessageV3::ScanningFinished(m) => ButtplugServerMessageV2::ScanningFinished(m), 158 ButtplugServerMessageV3::DeviceAdded(m) => ButtplugServerMessageV2::DeviceAdded(m.into()), 159 ButtplugServerMessageV3::DeviceList(m) => ButtplugServerMessageV2::DeviceList(m.into()), 160 ButtplugServerMessageV3::SensorReading(_) => ButtplugServerMessageV2::Error(ErrorV0::from( 161 ButtplugError::from(ButtplugMessageError::MessageConversionError( 162 "SensorReading cannot be converted to Buttplug Message Spec V2".to_owned(), 163 )), 164 )), 165 } 166 } 167} 168 169impl TryFrom<ButtplugServerMessageV4> for ButtplugServerMessageV3 { 170 type Error = ButtplugMessageError; 171 172 fn try_from( 173 value: ButtplugServerMessageV4, 174 ) -> Result<Self, <ButtplugServerMessageV3 as TryFrom<ButtplugServerMessageV4>>::Error> { 175 match value { 176 // Direct conversions 177 ButtplugServerMessageV4::Ok(m) => Ok(ButtplugServerMessageV3::Ok(m)), 178 ButtplugServerMessageV4::Error(m) => Ok(ButtplugServerMessageV3::Error(m)), 179 ButtplugServerMessageV4::ServerInfo(m) => Ok(ButtplugServerMessageV3::ServerInfo(m.into())), 180 ButtplugServerMessageV4::ScanningFinished(m) => { 181 Ok(ButtplugServerMessageV3::ScanningFinished(m)) 182 } 183 ButtplugServerMessageV4::DeviceList(m) => Ok(ButtplugServerMessageV3::DeviceList(m.into())), 184 // All other messages (SensorReading) requires device manager context. 185 _ => Err(ButtplugMessageError::MessageConversionError(format!( 186 "Cannot convert message {value:?} to current message spec while lacking state." 187 ))), 188 } 189 } 190} 191 192#[derive(Copy, Debug, Clone, PartialEq, Eq, Hash, Display, Serialize, Deserialize)] 193pub enum ButtplugDeviceMessageNameV3 { 194 LinearCmd, 195 RotateCmd, 196 StopDeviceCmd, 197 ScalarCmd, 198 SensorReadCmd, 199 SensorSubscribeCmd, 200 SensorUnsubscribeCmd, 201}