use super::message::{
self,
ButtplugMessageSpecVersion,
ErrorCode,
InputType,
OutputType,
serializer::ButtplugSerializerError,
};
use futures::future::BoxFuture;
use serde::{Deserialize, Serialize};
use thiserror::Error;
pub type ButtplugResult<T = ()> = Result<T, ButtplugError>;
macro_rules! impl_error_to_future {
($($error_type:ty),* $(,)?) => {
$(
impl<T> From<$error_type> for BoxFuture<'static, Result<T, ButtplugError>>
where
T: Send + 'static,
{
fn from(err: $error_type) -> BoxFuture<'static, Result<T, ButtplugError>> {
ButtplugError::from(err).into()
}
}
)*
};
}
impl_error_to_future!(
ButtplugHandshakeError,
ButtplugMessageError,
ButtplugPingError,
ButtplugDeviceError,
ButtplugUnknownError,
);
#[derive(Debug, Error, Display, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ButtplugHandshakeError {
UnexpectedHandshakeMessageReceived(String),
RequestServerInfoExpected,
HandshakeAlreadyHappened,
ReconnectDenied,
MessageSpecVersionMismatch(ButtplugMessageSpecVersion, ButtplugMessageSpecVersion),
UntypedDeserializedError(String),
UnhandledMessageSpecVersionRequested(ButtplugMessageSpecVersion),
}
#[derive(Debug, Error, Display, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ButtplugMessageError {
UnexpectedMessageType(String),
VersionError(String, String, String),
MessageConversionError(String),
InvalidMessageContents(String),
UnhandledMessage(String),
ValidationError(String),
#[error(transparent)]
MessageSerializationError(#[from] ButtplugSerializerError),
UntypedDeserializedError(String),
}
#[derive(Debug, Error, Display, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ButtplugPingError {
PingedOut,
PingTimerNotRunning,
InvalidPingTimeout,
UntypedDeserializedError(String),
}
#[derive(Debug, Error, Display, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ButtplugDeviceError {
DeviceNotConnected(String),
MessageNotSupported(String),
DeviceFeatureCountMismatch(u32, u32),
DeviceFeatureIndexError(u32, u32),
DeviceFeatureMismatch(String),
DeviceSensorIndexError(u32, u32),
DeviceConnectionError(String),
DeviceCommunicationError(String),
DeviceStepRangeError(i32, i32),
DeviceNoOutputError(OutputType),
DeviceNoInputError(InputType),
InvalidEndpoint(String),
UnhandledCommand(String),
DeviceSpecificError(String),
DeviceNotAvailable(u32),
DeviceScanningAlreadyStarted,
DeviceScanningAlreadyStopped,
DevicePermissionError(String),
DeviceCommandSignError,
ProtocolAttributesNotFound(String),
ProtocolNotImplemented(String),
ProtocolSpecificError(String, String),
ProtocolRequirementError(String),
ProtocolAlreadyAdded(String),
UntypedDeserializedError(String),
DeviceConfigurationError(String),
DeviceOutputTypeMismatch(u32, OutputType, OutputType),
DeviceInputTypeMismatch(u32, InputType),
ProtocolInputNotSupported(InputType),
OutputNotSupported(OutputType),
}
#[derive(Debug, Error, Display, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ButtplugUnknownError {
NoDeviceCommManagers,
UnexpectedType(String),
UntypedDeserializedError(String),
DeviceManagerNotRunning,
}
#[derive(Debug, Error, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ButtplugError {
#[error(transparent)]
ButtplugHandshakeError(#[from] ButtplugHandshakeError),
#[error(transparent)]
ButtplugMessageError(#[from] ButtplugMessageError),
#[error(transparent)]
ButtplugPingError(#[from] ButtplugPingError),
#[error(transparent)]
ButtplugDeviceError(#[from] ButtplugDeviceError),
#[error(transparent)]
ButtplugUnknownError(#[from] ButtplugUnknownError),
}
impl From<message::ErrorV0> for ButtplugError {
fn from(error: message::ErrorV0) -> Self {
match error.error_code() {
ErrorCode::ErrorDevice => {
ButtplugDeviceError::UntypedDeserializedError(error.error_message().clone()).into()
}
ErrorCode::ErrorMessage => {
ButtplugMessageError::UntypedDeserializedError(error.error_message().clone()).into()
}
ErrorCode::ErrorHandshake => {
ButtplugHandshakeError::UntypedDeserializedError(error.error_message().clone()).into()
}
ErrorCode::ErrorUnknown => {
ButtplugUnknownError::UntypedDeserializedError(error.error_message().clone()).into()
}
ErrorCode::ErrorPing => {
ButtplugPingError::UntypedDeserializedError(error.error_message().clone()).into()
}
}
}
}