use buttplug_core::message::{ ButtplugClientMessageV4, ButtplugMessage, ButtplugMessageFinalizer, ButtplugServerMessageV4, serializer::{ ButtplugMessageSerializer, ButtplugSerializedMessage, ButtplugSerializerError, json_serializer::{create_message_validator, deserialize_to_message, vec_to_protocol_json}, }, }; use jsonschema::Validator; use serde::{Deserialize, Serialize}; use std::fmt::Debug; pub struct ButtplugClientJSONSerializerImpl { validator: Validator, } impl Default for ButtplugClientJSONSerializerImpl { fn default() -> Self { Self { validator: create_message_validator(), } } } impl ButtplugClientJSONSerializerImpl { pub fn deserialize( &self, msg: &ButtplugSerializedMessage, ) -> Result, ButtplugSerializerError> where T: serde::de::DeserializeOwned + ButtplugMessageFinalizer + Clone + Debug, { if let ButtplugSerializedMessage::Text(text_msg) = msg { deserialize_to_message::(Some(&self.validator), text_msg) } else { Err(ButtplugSerializerError::BinaryDeserializationError) } } pub fn serialize(&self, msg: &[T]) -> ButtplugSerializedMessage where T: ButtplugMessage + Serialize + Deserialize<'static>, { ButtplugSerializedMessage::Text(vec_to_protocol_json(msg)) } } #[derive(Default)] pub struct ButtplugClientJSONSerializer { serializer_impl: ButtplugClientJSONSerializerImpl, } impl ButtplugMessageSerializer for ButtplugClientJSONSerializer { type Inbound = ButtplugServerMessageV4; type Outbound = ButtplugClientMessageV4; fn deserialize( &self, msg: &ButtplugSerializedMessage, ) -> Result, ButtplugSerializerError> { self.serializer_impl.deserialize(msg) } fn serialize(&self, msg: &[Self::Outbound]) -> ButtplugSerializedMessage { self.serializer_impl.serialize(msg) } } #[cfg(test)] mod test { use super::*; use buttplug_core::message::{ BUTTPLUG_CURRENT_API_MAJOR_VERSION, BUTTPLUG_CURRENT_API_MINOR_VERSION, RequestServerInfoV4, }; #[test] fn test_client_incorrect_messages() { let incorrect_incoming_messages = vec![ // Not valid JSON "not a json message", // Valid json object but no contents "{}", // Valid json but not an object "[]", // Not a message type "[{\"NotAMessage\":{}}]", // Valid json and message type but not in correct format "[{\"Ok\":[]}]", // Valid json and message type but not in correct format "[{\"Ok\":{}}]", // Valid json and message type but not an array. "{\"Ok\":{\"Id\":0}}", // Valid json and message type but not an array. "[{\"Ok\":{\"Id\":0}}]", // Valid json and message type but with extra content "[{\"Ok\":{\"NotAField\":\"NotAValue\",\"Id\":1}}]", ]; let serializer = ButtplugClientJSONSerializer::default(); let _ = serializer.serialize(&vec![ RequestServerInfoV4::new( "test client", BUTTPLUG_CURRENT_API_MAJOR_VERSION, BUTTPLUG_CURRENT_API_MINOR_VERSION, ) .into(), ]); for msg in incorrect_incoming_messages { let res = serializer.deserialize(&ButtplugSerializedMessage::Text(msg.to_owned())); assert!(res.is_err(), "{} should be an error", msg); if let Err(ButtplugSerializerError::MessageSpecVersionNotReceived) = res { assert!(false, "Wrong error!"); } } } }