Skip to main content

flare_core/common/serializer/
formats.rs

1//! 内置序列化格式实现
2//!
3//! 提供常用的序列化格式实现
4
5use super::traits::Serializer;
6use crate::common::error::{FlareError, Result};
7use crate::common::protobuf_decoder::{ProtobufDecoder, safe_protobuf_decode};
8use crate::common::protocol::{Frame, SerializationFormat};
9
10/// Protobuf 序列化器
11pub struct ProtobufSerializer;
12
13impl Serializer for ProtobufSerializer {
14    fn serialize(&self, frame: &Frame) -> Result<Vec<u8>> {
15        let mut buf = Vec::new();
16        prost::Message::encode(frame, &mut buf)
17            .map_err(|e| FlareError::encoding_error(format!("Protobuf encode error: {}", e)))?;
18        Ok(buf)
19    }
20
21    fn deserialize(&self, data: &[u8]) -> Result<Frame> {
22        // 使用安全的protobuf解码函数
23        safe_protobuf_decode::<Frame>(data)
24            .map_err(|e| FlareError::deserialization_error(format!("Protobuf decode error: {}", e)))
25    }
26
27    fn format(&self) -> SerializationFormat {
28        SerializationFormat::Protobuf
29    }
30
31    fn name(&self) -> &'static str {
32        "protobuf"
33    }
34
35    fn can_detect(&self, data: &[u8]) -> bool {
36        // Protobuf 没有标准的魔数,但可以尝试解析
37        // 这里简化处理,总是返回 true,让解析器尝试
38        !data.is_empty()
39    }
40}
41
42/// 带粘包处理的 Protobuf 序列化器
43///
44/// 用于处理带长度前缀的 Protobuf 消息,防止将 varint 长度前缀误认为字符串内容
45/// 这解决了 protobuf string 字段前出现 "\x0c" 的问题,该问题是由于 length varint
46/// 被当成字符串解码导致的
47pub struct FramedProtobufSerializer {
48    /// 用于处理粘包的解码器
49    _decoder: Option<ProtobufDecoder<Frame>>,
50}
51
52impl FramedProtobufSerializer {
53    pub fn new() -> Self {
54        Self { _decoder: None }
55    }
56
57    /// 为当前线程/连接创建独立的解码器实例
58    #[allow(dead_code)]
59    fn get_or_create_decoder(&mut self) -> &mut ProtobufDecoder<Frame> {
60        if self._decoder.is_none() {
61            self._decoder = Some(ProtobufDecoder::new());
62        }
63        self._decoder.as_mut().unwrap()
64    }
65}
66
67impl Default for FramedProtobufSerializer {
68    fn default() -> Self {
69        Self::new()
70    }
71}
72
73impl Serializer for FramedProtobufSerializer {
74    fn serialize(&self, frame: &Frame) -> Result<Vec<u8>> {
75        let mut buf = Vec::new();
76        prost::Message::encode(frame, &mut buf).map_err(|e| {
77            FlareError::encoding_error(format!("Framed Protobuf encode error: {}", e))
78        })?;
79
80        // 为消息添加长度前缀
81        let mut prefixed_buf = Vec::new();
82        prost::encoding::encode_varint(buf.len() as u64, &mut prefixed_buf);
83        prefixed_buf.extend_from_slice(&buf);
84
85        Ok(prefixed_buf)
86    }
87
88    fn deserialize(&self, data: &[u8]) -> Result<Frame> {
89        // 对于带前缀的protobuf消息,需要使用专用解码器
90        // 这里我们直接使用安全解码函数,因为单次解码不需要维护状态
91        safe_protobuf_decode::<Frame>(data).map_err(|e| {
92            FlareError::deserialization_error(format!("Framed Protobuf decode error: {}", e))
93        })
94    }
95
96    fn format(&self) -> SerializationFormat {
97        SerializationFormat::Protobuf
98    }
99
100    fn name(&self) -> &'static str {
101        "framed_protobuf"
102    }
103
104    fn can_detect(&self, data: &[u8]) -> bool {
105        // 检查是否可能是带前缀的protobuf消息
106        !data.is_empty()
107    }
108}
109
110/// JSON 序列化器
111pub struct JsonSerializer;
112
113impl Serializer for JsonSerializer {
114    fn serialize(&self, frame: &Frame) -> Result<Vec<u8>> {
115        serde_json::to_vec(frame)
116            .map_err(|e| FlareError::serialization_error(format!("JSON encode error: {}", e)))
117    }
118
119    fn deserialize(&self, data: &[u8]) -> Result<Frame> {
120        serde_json::from_slice(data)
121            .map_err(|e| FlareError::deserialization_error(format!("JSON decode error: {}", e)))
122    }
123
124    fn format(&self) -> SerializationFormat {
125        SerializationFormat::Json
126    }
127
128    fn name(&self) -> &'static str {
129        "json"
130    }
131
132    fn can_detect(&self, data: &[u8]) -> bool {
133        // JSON 通常以 { 或 [ 开头
134        if data.is_empty() {
135            return false;
136        }
137        let first = data[0];
138        first == b'{' || first == b'['
139    }
140}