Buttplug sex toy control library
1use buttplug_core::message::{ 2 ButtplugClientMessageV4, 3 ButtplugMessage, 4 ButtplugMessageFinalizer, 5 ButtplugServerMessageV4, 6 serializer::{ 7 ButtplugMessageSerializer, 8 ButtplugSerializedMessage, 9 ButtplugSerializerError, 10 json_serializer::{create_message_validator, deserialize_to_message, vec_to_protocol_json}, 11 }, 12}; 13use jsonschema::Validator; 14use serde::{Deserialize, Serialize}; 15use std::fmt::Debug; 16 17pub struct ButtplugClientJSONSerializerImpl { 18 validator: Validator, 19} 20 21impl Default for ButtplugClientJSONSerializerImpl { 22 fn default() -> Self { 23 Self { 24 validator: create_message_validator(), 25 } 26 } 27} 28 29impl ButtplugClientJSONSerializerImpl { 30 pub fn deserialize<T>( 31 &self, 32 msg: &ButtplugSerializedMessage, 33 ) -> Result<Vec<T>, ButtplugSerializerError> 34 where 35 T: serde::de::DeserializeOwned + ButtplugMessageFinalizer + Clone + Debug, 36 { 37 if let ButtplugSerializedMessage::Text(text_msg) = msg { 38 deserialize_to_message::<T>(Some(&self.validator), text_msg) 39 } else { 40 Err(ButtplugSerializerError::BinaryDeserializationError) 41 } 42 } 43 44 pub fn serialize<T>(&self, msg: &[T]) -> ButtplugSerializedMessage 45 where 46 T: ButtplugMessage + Serialize + Deserialize<'static>, 47 { 48 ButtplugSerializedMessage::Text(vec_to_protocol_json(msg)) 49 } 50} 51 52#[derive(Default)] 53pub struct ButtplugClientJSONSerializer { 54 serializer_impl: ButtplugClientJSONSerializerImpl, 55} 56 57impl ButtplugMessageSerializer for ButtplugClientJSONSerializer { 58 type Inbound = ButtplugServerMessageV4; 59 type Outbound = ButtplugClientMessageV4; 60 61 fn deserialize( 62 &self, 63 msg: &ButtplugSerializedMessage, 64 ) -> Result<Vec<Self::Inbound>, ButtplugSerializerError> { 65 self.serializer_impl.deserialize(msg) 66 } 67 68 fn serialize(&self, msg: &[Self::Outbound]) -> ButtplugSerializedMessage { 69 self.serializer_impl.serialize(msg) 70 } 71} 72 73#[cfg(test)] 74mod test { 75 use super::*; 76 use buttplug_core::message::{ 77 BUTTPLUG_CURRENT_API_MAJOR_VERSION, 78 BUTTPLUG_CURRENT_API_MINOR_VERSION, 79 RequestServerInfoV4, 80 }; 81 82 #[test] 83 fn test_client_incorrect_messages() { 84 let incorrect_incoming_messages = vec![ 85 // Not valid JSON 86 "not a json message", 87 // Valid json object but no contents 88 "{}", 89 // Valid json but not an object 90 "[]", 91 // Not a message type 92 "[{\"NotAMessage\":{}}]", 93 // Valid json and message type but not in correct format 94 "[{\"Ok\":[]}]", 95 // Valid json and message type but not in correct format 96 "[{\"Ok\":{}}]", 97 // Valid json and message type but not an array. 98 "{\"Ok\":{\"Id\":0}}", 99 // Valid json and message type but not an array. 100 "[{\"Ok\":{\"Id\":0}}]", 101 // Valid json and message type but with extra content 102 "[{\"Ok\":{\"NotAField\":\"NotAValue\",\"Id\":1}}]", 103 ]; 104 let serializer = ButtplugClientJSONSerializer::default(); 105 let _ = serializer.serialize(&vec![ 106 RequestServerInfoV4::new( 107 "test client", 108 BUTTPLUG_CURRENT_API_MAJOR_VERSION, 109 BUTTPLUG_CURRENT_API_MINOR_VERSION, 110 ) 111 .into(), 112 ]); 113 for msg in incorrect_incoming_messages { 114 let res = serializer.deserialize(&ButtplugSerializedMessage::Text(msg.to_owned())); 115 assert!(res.is_err(), "{} should be an error", msg); 116 if let Err(ButtplugSerializerError::MessageSpecVersionNotReceived) = res { 117 assert!(false, "Wrong error!"); 118 } 119 } 120 } 121}