use std::fmt::Debug;
use serde::{Serialize, Deserialize};
use once_cell::sync::Lazy;
pub trait ReactiveMessagingSerializer<LocalPeerMessages: ReactiveMessagingSerializer<LocalPeerMessages> + Send + PartialEq + Debug> {
fn serialize(remote_message: &LocalPeerMessages, buffer: &mut Vec<u8>);
fn processor_error_message(err: String) -> LocalPeerMessages;
}
pub trait ReactiveMessagingDeserializer<T> {
fn deserialize(remote_message: &[u8]) -> Result<T, Box<dyn std::error::Error + Sync + Send>>;
}
static RON_DESERIALIZER_CONFIG: Lazy<ron::Options> = Lazy::new(ron::Options::default);
#[inline(always)]
pub fn ron_serializer<T: ?Sized + Serialize>(message: &T, buffer: &mut Vec<u8>) -> Result<(), ron::Error> {
buffer.clear();
let mut serializer = ron::Serializer::with_options(buffer, None, ron::Options::default())?;
message.serialize(&mut serializer)?;
Ok(())
}
#[inline(always)]
pub fn ron_deserializer<T: for<'r> Deserialize<'r>>(message: &[u8]) -> Result<T, Box<dyn std::error::Error + Sync + Send>> {
RON_DESERIALIZER_CONFIG.from_bytes(message)
.map_err(|err| Box::from(format!("RON deserialization error for message '{:?}': {}", std::str::from_utf8(message), err)))
}
#[cfg(any(test,doc))]
mod tests {
use super::*;
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub enum Messages {
Echo(String),
Recursive(Option<Box<Messages>>)
}
#[cfg_attr(not(doc),test)]
fn ron_serde_for_server_only() {
let mut buffer = Vec::<u8>::with_capacity(16);
let message = Messages::Echo(String::from("This is an error message"));
let expected = "Echo(\"This is an error message\")";
ron_serializer(&message, &mut buffer).expect("calling `ron_serializer()`");
let observed = String::from_utf8(buffer).expect("Ron should be utf-8");
assert_eq!(observed, expected, "RON serialization is not good");
let message = "Recursive(Some(Recursive(Some(Echo(\"here it is\")))))".as_bytes();
let expected = Messages::Recursive(Some(Box::new(Messages::Recursive(Some(Box::new(Messages::Echo(String::from("here it is"))))))));
let observed = ron_deserializer::<Messages>(message)
.expect("RON deserialization failed");
assert_eq!(observed, expected, "RON deserialization is not good");
}
}