use crate::common::protocol::SerializationFormat;
use super::traits::Serializer;
use super::formats::{ProtobufSerializer, JsonSerializer};
use std::sync::Arc;
use std::collections::HashMap;
use std::sync::RwLock;
lazy_static::lazy_static! {
static ref SERIALIZATION_REGISTRY: SerializationRegistry = {
let registry = SerializationRegistry::new();
registry.register_defaults();
registry
};
}
pub struct SerializationRegistry {
serializers: Arc<RwLock<HashMap<String, Arc<dyn Serializer>>>>,
}
impl SerializationRegistry {
pub fn new() -> Self {
Self {
serializers: Arc::new(RwLock::new(HashMap::new())),
}
}
pub fn register_defaults(&self) {
self.register("protobuf", Arc::new(ProtobufSerializer));
self.register("json", Arc::new(JsonSerializer));
}
pub fn register(&self, name: &str, serializer: Arc<dyn Serializer>) {
if let Ok(mut serializers) = self.serializers.write() {
serializers.insert(name.to_string(), serializer);
}
}
pub fn find(&self, name: &str) -> Option<Arc<dyn Serializer>> {
self.serializers
.read()
.ok()
.and_then(|serializers| serializers.get(name).map(|s| Arc::clone(s)))
}
pub fn find_by_format(&self, format: SerializationFormat) -> Option<Arc<dyn Serializer>> {
let name = match format {
SerializationFormat::Protobuf => "protobuf",
SerializationFormat::Json => "json",
};
self.find(name)
}
pub fn auto_detect(&self, data: &[u8]) -> Vec<Arc<dyn Serializer>> {
let mut detected = Vec::new();
if let Ok(serializers) = self.serializers.read() {
for serializer in serializers.values() {
if serializer.can_detect(data) {
detected.push(Arc::clone(serializer));
}
}
}
detected
}
pub fn global() -> &'static SerializationRegistry {
&SERIALIZATION_REGISTRY
}
}
pub struct SerializationUtil;
impl SerializationUtil {
pub fn get_serializer(format: SerializationFormat) -> Option<Arc<dyn Serializer>> {
SerializationRegistry::global().find_by_format(format)
}
pub fn get_serializer_by_name(name: &str) -> Option<Arc<dyn Serializer>> {
SerializationRegistry::global().find(name)
}
pub fn auto_detect(data: &[u8]) -> Vec<Arc<dyn Serializer>> {
SerializationRegistry::global().auto_detect(data)
}
pub fn register_custom(serializer: Arc<dyn Serializer>) {
SerializationRegistry::global().register(serializer.name(), serializer);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialization_registry() {
let registry = SerializationRegistry::new();
registry.register_defaults();
assert!(registry.find("protobuf").is_some());
assert!(registry.find("json").is_some());
assert!(registry.find("unknown").is_none());
}
#[test]
fn test_auto_detect_json() {
let data = b"{\"message_id\":\"test\"}";
let registry = SerializationRegistry::new();
registry.register_defaults();
let serializers = registry.auto_detect(data);
assert!(serializers.iter().any(|s| s.name() == "json"));
}
}