codeprism_storage/
serialization.rs1use anyhow::Result;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum SerializationFormat {
9 Bincode,
10 Json,
11 MessagePack,
12}
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum CompressionAlgorithm {
17 None,
18 Gzip,
19 Zstd,
20}
21
22pub struct Serializer {
24 format: SerializationFormat,
25 compression: CompressionAlgorithm,
26}
27
28impl Serializer {
29 pub fn new(format: SerializationFormat, compression: CompressionAlgorithm) -> Self {
31 Self {
32 format,
33 compression,
34 }
35 }
36
37 pub fn serialize<T>(&self, value: &T) -> Result<Vec<u8>>
39 where
40 T: Serialize,
41 {
42 let serialized = match self.format {
44 SerializationFormat::Bincode => bincode::serialize(value)?,
45 SerializationFormat::Json => serde_json::to_vec(value)?,
46 SerializationFormat::MessagePack => rmp_serde::to_vec(value)?,
47 };
48
49 let compressed = match self.compression {
51 CompressionAlgorithm::None => serialized,
52 CompressionAlgorithm::Gzip => {
53 use std::io::Write;
54 let mut encoder =
55 flate2::write::GzEncoder::new(Vec::new(), flate2::Compression::default());
56 encoder.write_all(&serialized)?;
57 encoder.finish()?
58 }
59 CompressionAlgorithm::Zstd => zstd::bulk::compress(&serialized, 3)?,
60 };
61
62 Ok(compressed)
63 }
64
65 pub fn deserialize<T>(&self, data: &[u8]) -> Result<T>
67 where
68 T: for<'de> Deserialize<'de>,
69 {
70 let decompressed = match self.compression {
72 CompressionAlgorithm::None => data.to_vec(),
73 CompressionAlgorithm::Gzip => {
74 use std::io::Read;
75 let mut decoder = flate2::read::GzDecoder::new(data);
76 let mut decompressed = Vec::new();
77 decoder.read_to_end(&mut decompressed)?;
78 decompressed
79 }
80 CompressionAlgorithm::Zstd => {
81 zstd::bulk::decompress(data, 10 * 1024 * 1024)? }
83 };
84
85 let value = match self.format {
87 SerializationFormat::Bincode => bincode::deserialize(&decompressed)?,
88 SerializationFormat::Json => serde_json::from_slice(&decompressed)?,
89 SerializationFormat::MessagePack => rmp_serde::from_slice(&decompressed)?,
90 };
91
92 Ok(value)
93 }
94}
95
96impl Default for Serializer {
97 fn default() -> Self {
99 Self {
100 format: SerializationFormat::Bincode,
101 compression: CompressionAlgorithm::Gzip,
102 }
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109
110 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
111 struct TestData {
112 name: String,
113 value: i32,
114 items: Vec<String>,
115 }
116
117 #[test]
118 fn test_serialization_bincode() {
119 let serializer = Serializer::new(SerializationFormat::Bincode, CompressionAlgorithm::None);
120 let data = TestData {
121 name: "test".to_string(),
122 value: 42,
123 items: vec!["a".to_string(), "b".to_string()],
124 };
125
126 let serialized = serializer.serialize(&data).unwrap();
127 let deserialized: TestData = serializer.deserialize(&serialized).unwrap();
128
129 assert_eq!(data, deserialized);
130 }
131
132 #[test]
133 fn test_serialization_json() {
134 let serializer = Serializer::new(SerializationFormat::Json, CompressionAlgorithm::None);
135 let data = TestData {
136 name: "test".to_string(),
137 value: 42,
138 items: vec!["a".to_string(), "b".to_string()],
139 };
140
141 let serialized = serializer.serialize(&data).unwrap();
142 let deserialized: TestData = serializer.deserialize(&serialized).unwrap();
143
144 assert_eq!(data, deserialized);
145 }
146
147 #[test]
148 fn test_compression_gzip() {
149 let serializer = Serializer::new(SerializationFormat::Json, CompressionAlgorithm::Gzip);
150 let data = TestData {
151 name: "test".to_string(),
152 value: 42,
153 items: vec!["a".to_string(), "b".to_string()],
154 };
155
156 let serialized = serializer.serialize(&data).unwrap();
157 let deserialized: TestData = serializer.deserialize(&serialized).unwrap();
158
159 assert_eq!(data, deserialized);
160 }
161}