use serde::{Deserialize, Serialize};
use thiserror::Error;
mod json;
pub use json::JsonSerializer;
#[cfg(feature = "messagepack")]
mod messagepack;
#[cfg(feature = "messagepack")]
pub use messagepack::MessagePackSerializer;
#[cfg(feature = "cbor")]
mod cbor;
#[cfg(feature = "cbor")]
pub use cbor::CborSerializer;
#[cfg(feature = "bincode")]
mod bincode;
#[cfg(feature = "bincode")]
pub use self::bincode::BincodeSerializer;
#[non_exhaustive]
#[derive(Debug, Error)]
pub enum SerializationError {
#[error("JSON error: {0}")]
JsonError(#[from] serde_json::Error),
#[cfg(feature = "messagepack")]
#[error("MessagePack error: {0}")]
MessagePackError(#[from] rmp_serde::encode::Error),
#[cfg(feature = "messagepack")]
#[error("MessagePack decode error: {0}")]
MessagePackDecodeError(#[from] rmp_serde::decode::Error),
#[error("Serialization failed: {0}")]
SerializationFailed(String),
#[error("Deserialization failed: {0}")]
DeserializationFailed(String),
#[error("Unsupported serialization format")]
UnsupportedFormat,
}
pub trait Serializer: Send + Sync {
fn serialize<T: Serialize>(&self, data: &T) -> Result<Vec<u8>, SerializationError>;
fn deserialize<T: for<'de> Deserialize<'de>>(
&self,
bytes: &[u8],
) -> Result<T, SerializationError>;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SerializationFormat {
Json,
#[cfg(feature = "messagepack")]
MessagePack,
#[cfg(feature = "cbor")]
Cbor,
#[cfg(feature = "bincode")]
Bincode,
}
impl SerializationFormat {
pub fn name(&self) -> &'static str {
match self {
SerializationFormat::Json => "json",
#[cfg(feature = "messagepack")]
SerializationFormat::MessagePack => "messagepack",
#[cfg(feature = "cbor")]
SerializationFormat::Cbor => "cbor",
#[cfg(feature = "bincode")]
SerializationFormat::Bincode => "bincode",
}
}
pub fn serialize<T: Serialize>(&self, data: &T) -> Result<Vec<u8>, SerializationError> {
match self {
SerializationFormat::Json => JsonSerializer.serialize(data),
#[cfg(feature = "messagepack")]
SerializationFormat::MessagePack => MessagePackSerializer.serialize(data),
#[cfg(feature = "cbor")]
SerializationFormat::Cbor => CborSerializer.serialize(data),
#[cfg(feature = "bincode")]
SerializationFormat::Bincode => BincodeSerializer.serialize(data),
}
}
pub fn deserialize<T: for<'de> Deserialize<'de>>(
&self,
bytes: &[u8],
) -> Result<T, SerializationError> {
match self {
SerializationFormat::Json => JsonSerializer.deserialize(bytes),
#[cfg(feature = "messagepack")]
SerializationFormat::MessagePack => MessagePackSerializer.deserialize(bytes),
#[cfg(feature = "cbor")]
SerializationFormat::Cbor => CborSerializer.deserialize(bytes),
#[cfg(feature = "bincode")]
SerializationFormat::Bincode => BincodeSerializer.deserialize(bytes),
}
}
}
impl Default for SerializationFormat {
fn default() -> Self {
Self::Json
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialization_format_name() {
assert_eq!(SerializationFormat::Json.name(), "json");
#[cfg(feature = "messagepack")]
assert_eq!(SerializationFormat::MessagePack.name(), "messagepack");
#[cfg(feature = "cbor")]
assert_eq!(SerializationFormat::Cbor.name(), "cbor");
#[cfg(feature = "bincode")]
assert_eq!(SerializationFormat::Bincode.name(), "bincode");
}
#[test]
fn test_serialization_format_default() {
let format = SerializationFormat::default();
assert_eq!(format, SerializationFormat::Json);
}
#[test]
fn test_serialization_format_serialize_deserialize() {
let format = SerializationFormat::Json;
let data = serde_json::json!({"test": "value"});
let bytes = format.serialize(&data).unwrap();
let restored: serde_json::Value = format.deserialize(&bytes).unwrap();
assert_eq!(restored["test"], "value");
}
}