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");
    }
}