Buttplug sex toy control library
at master 9.3 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 8//! Buttplug Error Structs/Enums, representing protocol errors. 9 10use super::message::{ 11 self, 12 ButtplugMessageSpecVersion, 13 ErrorCode, 14 InputType, 15 OutputType, 16 serializer::ButtplugSerializerError, 17}; 18use futures::future::BoxFuture; 19use serde::{Deserialize, Serialize}; 20use thiserror::Error; 21 22pub type ButtplugResult<T = ()> = Result<T, ButtplugError>; 23 24/// Handshake errors occur while a client is connecting to a server. This 25/// usually involves protocol handshake errors. For connector errors (i.e. when 26/// a remote network connection cannot be established), see 27/// [crate::connector::ButtplugConnectorError]. 28impl<T> From<ButtplugHandshakeError> for BoxFuture<'static, Result<T, ButtplugError>> 29where 30 T: Send + 'static, 31{ 32 fn from(err: ButtplugHandshakeError) -> BoxFuture<'static, Result<T, ButtplugError>> { 33 ButtplugError::from(err).into() 34 } 35} 36 37#[derive(Debug, Error, Display, Clone, PartialEq, Eq, Serialize, Deserialize)] 38pub enum ButtplugHandshakeError { 39 /// Expected either a ServerInfo or Error message, received {0} 40 UnexpectedHandshakeMessageReceived(String), 41 /// Expected a RequestServerInfo message to start connection. Message either not received or wrong message received. 42 RequestServerInfoExpected, 43 /// Handshake already happened, cannot run handshake again. 44 HandshakeAlreadyHappened, 45 /// Server has already connected and disconnected, cannot be reused 46 ReconnectDenied, 47 /// Server spec version ({0}) must be equal or greater than client version ({1}) 48 MessageSpecVersionMismatch(ButtplugMessageSpecVersion, ButtplugMessageSpecVersion), 49 /// Untyped Deserialized Error: {0} 50 UntypedDeserializedError(String), 51 /// Unhandled spec version requested, may require extra arguments to activate: {0} 52 UnhandledMessageSpecVersionRequested(ButtplugMessageSpecVersion), 53} 54 55/// Message errors occur when a message is somehow malformed on creation, or 56/// received unexpectedly by a client or server. 57impl<T> From<ButtplugMessageError> for BoxFuture<'static, Result<T, ButtplugError>> 58where 59 T: Send + 'static, 60{ 61 fn from(err: ButtplugMessageError) -> BoxFuture<'static, Result<T, ButtplugError>> { 62 ButtplugError::from(err).into() 63 } 64} 65 66#[derive(Debug, Error, Display, Clone, PartialEq, Eq, Serialize, Deserialize)] 67pub enum ButtplugMessageError { 68 /// Got unexpected message type: {0} 69 UnexpectedMessageType(String), 70 /// {0} {1} cannot be converted to {2} 71 VersionError(String, String, String), 72 /// Message conversion error: {0} 73 MessageConversionError(String), 74 /// Invalid message contents: {0} 75 InvalidMessageContents(String), 76 /// Unhandled message type: {0} 77 UnhandledMessage(String), 78 /// Message validation error(s): {0} 79 ValidationError(String), 80 /// Message serialization error 81 #[error(transparent)] 82 MessageSerializationError(#[from] ButtplugSerializerError), 83 /// Untyped Deserialized Error: {0} 84 UntypedDeserializedError(String), 85} 86 87/// Ping errors occur when a server requires a ping response (set up during 88/// connection handshake), and the client does not return a response in the 89/// alloted timeframe. This also signifies a server disconnect. 90impl<T> From<ButtplugPingError> for BoxFuture<'static, Result<T, ButtplugError>> 91where 92 T: Send + 'static, 93{ 94 fn from(err: ButtplugPingError) -> BoxFuture<'static, Result<T, ButtplugError>> { 95 ButtplugError::from(err).into() 96 } 97} 98 99#[derive(Debug, Error, Display, Clone, PartialEq, Eq, Serialize, Deserialize)] 100pub enum ButtplugPingError { 101 /// Pinged timer exhausted, system has shut down. 102 PingedOut, 103 /// Ping timer not running. 104 PingTimerNotRunning, 105 /// Ping time must be greater than 0. 106 InvalidPingTimeout, 107 /// Untyped Deserialized Error: {0} 108 UntypedDeserializedError(String), 109} 110 111/// Device errors occur during device interactions, including sending 112/// unsupported message commands, addressing the wrong number of device 113/// attributes, etc... 114impl<T> From<ButtplugDeviceError> for BoxFuture<'static, Result<T, ButtplugError>> 115where 116 T: Send + 'static, 117{ 118 fn from(err: ButtplugDeviceError) -> BoxFuture<'static, Result<T, ButtplugError>> { 119 ButtplugError::from(err).into() 120 } 121} 122#[derive(Debug, Error, Display, Clone, PartialEq, Eq, Serialize, Deserialize)] 123pub enum ButtplugDeviceError { 124 /// Device {0} not connected 125 DeviceNotConnected(String), 126 /// Device does not support message type {0}. 127 MessageNotSupported(String), 128 /// Device only has {0} features, but {1} commands were sent. 129 DeviceFeatureCountMismatch(u32, u32), 130 /// Device only has {0} features, but was given an index of {1} 131 DeviceFeatureIndexError(u32, u32), 132 /// Device feature mismatch: {0} 133 DeviceFeatureMismatch(String), 134 /// Device only has {0} sensors, but was given an index of {1} 135 DeviceSensorIndexError(u32, u32), 136 /// Device connection error: {0} 137 DeviceConnectionError(String), 138 /// Device communication error: {0} 139 DeviceCommunicationError(String), 140 /// Device feature only has {0} steps for control, but {1} steps specified. 141 DeviceStepRangeError(i32, i32), 142 /// Device got {0} message but has no actuators 143 DeviceNoActuatorError(String), 144 /// Device got {0} message but has no sensors 145 DeviceNoSensorError(String), 146 /// Device does not have endpoint {0} 147 InvalidEndpoint(String), 148 /// Device does not handle command type: {0} 149 UnhandledCommand(String), 150 /// Device type specific error: {0}. 151 DeviceSpecificError(String), 152 /// No device available at index {0} 153 DeviceNotAvailable(u32), 154 /// Device scanning already started. 155 DeviceScanningAlreadyStarted, 156 /// Device scanning already stopped. 157 DeviceScanningAlreadyStopped, 158 /// Device permission error: {0} 159 DevicePermissionError(String), 160 /// Device command does not take negative numbers 161 DeviceCommandSignError, 162 /// {0} 163 ProtocolAttributesNotFound(String), 164 /// Protocol {0} not implemented in library 165 ProtocolNotImplemented(String), 166 /// {0} protocol specific error: {1} 167 ProtocolSpecificError(String, String), 168 /// {0} 169 ProtocolRequirementError(String), 170 /// Protocol already added to system {0}, 171 ProtocolAlreadyAdded(String), 172 /// Untyped Deserialized Error: {0} 173 UntypedDeserializedError(String), 174 /// Device Configuration Error: {0} 175 DeviceConfigurationError(String), 176 /// Output Type Mismatch: Index {0} got command for {1}, which is not valid 177 DeviceOutputTypeMismatch(u32, OutputType, OutputType), 178 /// Input Type Mismatch: Index {0} got command for {1}, which is not valid 179 DeviceInputTypeMismatch(u32, InputType), 180 /// Protocol does not have an implementation available for Sensor Type {0} 181 ProtocolInputNotSupported(InputType), 182 /// Device does not support {0} 183 OutputNotSupported(OutputType), 184} 185 186/// Unknown errors occur in exceptional circumstances where no other error type 187/// will suffice. These are rare and usually fatal (disconnecting) errors. 188impl<T> From<ButtplugUnknownError> for BoxFuture<'static, Result<T, ButtplugError>> 189where 190 T: Send + 'static, 191{ 192 fn from(err: ButtplugUnknownError) -> BoxFuture<'static, Result<T, ButtplugError>> { 193 ButtplugError::from(err).into() 194 } 195} 196 197#[derive(Debug, Error, Display, Clone, PartialEq, Eq, Serialize, Deserialize)] 198pub enum ButtplugUnknownError { 199 /// Cannot start scanning, no device communication managers available to use for scanning. 200 NoDeviceCommManagers, 201 /// Got unexpected enum type: {0} 202 UnexpectedType(String), 203 /// Untyped Deserialized Error: {0} 204 UntypedDeserializedError(String), 205 /// Device Manager has been shut down by its owning server and is no longer available. 206 DeviceManagerNotRunning, 207} 208 209/// Aggregation enum for protocol error types. 210#[derive(Debug, Error, Clone, PartialEq, Eq, Serialize, Deserialize)] 211pub enum ButtplugError { 212 #[error(transparent)] 213 ButtplugHandshakeError(#[from] ButtplugHandshakeError), 214 #[error(transparent)] 215 ButtplugMessageError(#[from] ButtplugMessageError), 216 #[error(transparent)] 217 ButtplugPingError(#[from] ButtplugPingError), 218 #[error(transparent)] 219 ButtplugDeviceError(#[from] ButtplugDeviceError), 220 #[error(transparent)] 221 ButtplugUnknownError(#[from] ButtplugUnknownError), 222} 223 224impl From<message::ErrorV0> for ButtplugError { 225 /// Turns a Buttplug Protocol Error Message [super::messages::Error] into a [ButtplugError] type. 226 fn from(error: message::ErrorV0) -> Self { 227 match error.error_code() { 228 ErrorCode::ErrorDevice => { 229 ButtplugDeviceError::UntypedDeserializedError(error.error_message().clone()).into() 230 } 231 ErrorCode::ErrorMessage => { 232 ButtplugMessageError::UntypedDeserializedError(error.error_message().clone()).into() 233 } 234 ErrorCode::ErrorHandshake => { 235 ButtplugHandshakeError::UntypedDeserializedError(error.error_message().clone()).into() 236 } 237 ErrorCode::ErrorUnknown => { 238 ButtplugUnknownError::UntypedDeserializedError(error.error_message().clone()).into() 239 } 240 ErrorCode::ErrorPing => { 241 ButtplugPingError::UntypedDeserializedError(error.error_message().clone()).into() 242 } 243 } 244 } 245}