use crate::{
errors::*,
message::{ButtplugMessage, ButtplugMessageValidator},
};
use getset::{CopyGetters, Getters};
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
#[derive(Debug, Clone, PartialEq, Eq, Copy, Serialize_repr, Deserialize_repr)]
#[repr(u8)]
pub enum ErrorCode {
ErrorUnknown = 0,
ErrorHandshake,
ErrorPing,
ErrorMessage,
ErrorDevice,
}
#[derive(Debug, Clone, Getters, CopyGetters, Serialize, Deserialize)]
pub struct ErrorV0 {
#[serde(rename = "Id")]
id: u32,
#[serde(rename = "ErrorCode")]
#[getset(get_copy = "pub")]
error_code: ErrorCode,
#[serde(rename = "ErrorMessage")]
#[getset(get = "pub")]
error_message: String,
#[serde(skip)]
original_error: Option<ButtplugError>,
}
impl ButtplugMessage for ErrorV0 {
fn id(&self) -> u32 {
self.id
}
fn set_id(&mut self, id: u32) {
self.id = id;
}
}
impl ButtplugMessageValidator for ErrorV0 {
}
impl PartialEq for ErrorV0 {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
&& self.error_code == other.error_code
&& self.error_message == other.error_message
}
}
impl ErrorV0 {
pub fn new(
error_code: ErrorCode,
error_message: &str,
original_error: Option<ButtplugError>,
) -> Self {
Self {
id: 0,
error_code,
error_message: error_message.to_string(),
original_error,
}
}
pub fn original_error(&self) -> ButtplugError {
if let Some(ref original_error) = self.original_error {
original_error.clone()
} else {
if let Ok(deserialized_msg) = serde_json::from_str(&self.error_message) {
return deserialized_msg;
}
ButtplugError::from(self.clone())
}
}
}
impl From<ButtplugError> for ErrorV0 {
fn from(error: ButtplugError) -> Self {
let code = match error {
ButtplugError::ButtplugDeviceError { .. } => ErrorCode::ErrorDevice,
ButtplugError::ButtplugMessageError { .. } => ErrorCode::ErrorMessage,
ButtplugError::ButtplugPingError { .. } => ErrorCode::ErrorPing,
ButtplugError::ButtplugHandshakeError { .. } => ErrorCode::ErrorHandshake,
ButtplugError::ButtplugUnknownError { .. } => ErrorCode::ErrorUnknown,
};
let msg = serde_json::to_string(&error).expect("ButtplugError derives Serialize");
ErrorV0::new(code, &msg, Some(error))
}
}
#[cfg(test)]
mod test {
use crate::message::{ButtplugServerMessageCurrent, ErrorCode, ErrorV0};
const ERROR_STR: &str = "{\"Error\":{\"Id\":0,\"ErrorCode\":1,\"ErrorMessage\":\"Test Error\"}}";
#[test]
fn test_error_serialize() {
let error = ButtplugServerMessageCurrent::Error(ErrorV0::new(
ErrorCode::ErrorHandshake,
"Test Error",
None,
));
let js = serde_json::to_string(&error).expect("Infallible serialization.");
assert_eq!(ERROR_STR, js);
}
}