use std::borrow::Cow;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use serde::{de::DeserializeOwned, Serialize};
use serde_json;
use crate::error::Result;
use rmp_serde::{decode, encode};
#[derive(Debug, Clone, Default)]
pub struct MessagePackSerializer;
impl MessagePackSerializer {
pub fn new() -> Self {
Self
}
}
impl crate::serialization::Serializer for MessagePackSerializer {
fn serialize<T: Serialize>(&self, value: &T) -> Result<Vec<u8>> {
encode::to_vec(value).map_err(|e| crate::error::CacheError::Serialization(e.to_string()))
}
fn deserialize<T: DeserializeOwned>(&self, data: &[u8]) -> Result<T> {
decode::from_read(data).map_err(|e| crate::error::CacheError::Serialization(e.to_string()))
}
}
impl crate::serialization::ZeroCopySerializer for MessagePackSerializer {
fn serialize_zero_copy<'a, T: Serialize>(&self, value: &'a T) -> Result<Cow<'a, [u8]>> {
let bytes = encode::to_vec(value)
.map_err(|e| crate::error::CacheError::Serialization(e.to_string()))?;
Ok(Cow::Owned(bytes))
}
fn deserialize_zero_copy<'a, T: DeserializeOwned + Clone>(
&self,
data: &'a [u8],
) -> Result<Cow<'a, T>> {
let value: T = decode::from_read(data)
.map_err(|e| crate::error::CacheError::Serialization(e.to_string()))?;
Ok(Cow::Owned(value))
}
}
#[derive(Debug, Clone, Default)]
pub struct CborSerializer;
impl CborSerializer {
pub fn new() -> Self {
Self
}
}
impl crate::serialization::Serializer for CborSerializer {
fn serialize<T: Serialize>(&self, value: &T) -> Result<Vec<u8>> {
let mut buf = Vec::new();
ciborium::into_writer(value, &mut buf)
.map_err(|e| crate::error::CacheError::Serialization(e.to_string()))?;
Ok(buf)
}
fn deserialize<T: DeserializeOwned>(&self, data: &[u8]) -> Result<T> {
ciborium::from_reader(data)
.map_err(|e| crate::error::CacheError::Serialization(e.to_string()))
}
}
#[derive(Default)]
pub struct SerializerRegistry {
serializers: Mutex<HashMap<String, Arc<dyn ErasedSerializer>>>,
}
pub trait ErasedSerializer: Send + Sync {
fn name(&self) -> &'static str;
fn serialize(&self, value: &serde_json::Value) -> Result<Vec<u8>>;
fn deserialize(&self, data: &[u8]) -> Result<serde_json::Value>;
}
impl ErasedSerializer for MessagePackSerializer {
fn name(&self) -> &'static str {
"msgpack"
}
fn serialize(&self, value: &serde_json::Value) -> Result<Vec<u8>> {
encode::to_vec(value).map_err(|e| crate::error::CacheError::Serialization(e.to_string()))
}
fn deserialize(&self, data: &[u8]) -> Result<serde_json::Value> {
decode::from_read(data).map_err(|e| crate::error::CacheError::Serialization(e.to_string()))
}
}
impl ErasedSerializer for CborSerializer {
fn name(&self) -> &'static str {
"cbor"
}
fn serialize(&self, value: &serde_json::Value) -> Result<Vec<u8>> {
let mut buf = Vec::new();
ciborium::into_writer(value, &mut buf)
.map_err(|e| crate::error::CacheError::Serialization(e.to_string()))?;
Ok(buf)
}
fn deserialize(&self, data: &[u8]) -> Result<serde_json::Value> {
ciborium::from_reader(data)
.map_err(|e| crate::error::CacheError::Serialization(e.to_string()))
}
}
impl SerializerRegistry {
pub fn new() -> Self {
Self {
serializers: Mutex::new(HashMap::new()),
}
}
pub fn register(&self, name: &str, serializer: Arc<dyn ErasedSerializer>) {
self.serializers
.lock()
.expect("SerializerRegistry lock poisoned")
.insert(name.to_string(), serializer);
}
pub fn get(&self, name: &str) -> Option<Arc<dyn ErasedSerializer>> {
self.serializers
.lock()
.expect("SerializerRegistry lock poisoned")
.get(name)
.cloned()
}
pub fn contains(&self, name: &str) -> bool {
self.serializers
.lock()
.expect("SerializerRegistry lock poisoned")
.contains_key(name)
}
pub fn remove(&self, name: &str) -> bool {
self.serializers
.lock()
.expect("SerializerRegistry lock poisoned")
.remove(name)
.is_some()
}
pub fn clear(&self) {
self.serializers
.lock()
.expect("SerializerRegistry lock poisoned")
.clear();
}
pub fn register_msgpack(&self) {
self.register("msgpack", Arc::new(MessagePackSerializer));
}
pub fn register_cbor(&self) {
self.register("cbor", Arc::new(CborSerializer));
}
pub fn register_all(&self) {
self.register_msgpack();
self.register_cbor();
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_messagepack_serializer() {
let serializer = MessagePackSerializer::new();
let value = serde_json::json!("test_value");
let bytes = serializer.serialize(&value).unwrap();
let decoded: serde_json::Value = serializer.deserialize(&bytes).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn test_cbor_serializer() {
let serializer = CborSerializer::new();
let value = serde_json::json!("test_value");
let bytes = serializer.serialize(&value).unwrap();
let decoded: serde_json::Value = serializer.deserialize(&bytes).unwrap();
assert_eq!(decoded, value);
}
#[test]
fn test_serializer_registry() {
let registry = SerializerRegistry::new();
assert!(!registry.contains("msgpack"));
registry.register("msgpack", Arc::new(MessagePackSerializer));
assert!(registry.contains("msgpack"));
let serializer = registry.get("msgpack");
assert!(serializer.is_some());
assert_eq!(serializer.unwrap().name(), "msgpack");
assert!(registry.remove("msgpack"));
assert!(!registry.contains("msgpack"));
registry.register("cbor", Arc::new(CborSerializer));
registry.clear();
assert!(!registry.contains("cbor"));
}
#[test]
fn test_erased_serializer() {
let registry = SerializerRegistry::new();
registry.register_all();
let serializer = registry.get("msgpack").unwrap();
let json_value = serde_json::json!({"key": "value"});
let bytes = serializer.serialize(&json_value).unwrap();
let decoded: serde_json::Value = serializer.deserialize(&bytes).unwrap();
assert_eq!(decoded, json_value);
}
}