rust_bitfield_serializer/
serializer.rs

1//! Bitfield serializer for converting between bitfield values and byte arrays.
2
3use crate::types::{BitfieldStruct, BitfieldValue, FieldType};
4use crate::utils::{BitReader, BitWriter};
5use std::collections::HashMap;
6
7/// A serializer for bitfield structures.
8#[derive(Debug, Clone)]
9pub struct BitfieldSerializer {
10    /// Registered bitfield structure definitions.
11    pub structs: HashMap<String, BitfieldStruct>,
12}
13
14impl BitfieldSerializer {
15    /// Create a new BitfieldSerializer.
16    pub fn new() -> Self {
17        Self {
18            structs: HashMap::new(),
19        }
20    }
21
22    /// Register a bitfield structure definition.
23    pub fn register_struct(&mut self, bitfield_struct: BitfieldStruct) {
24        self.structs
25            .insert(bitfield_struct.name.clone(), bitfield_struct);
26    }
27
28    /// Serialize a bitfield value to bytes.
29    pub fn serialize(&self, value: &BitfieldValue) -> Result<Vec<u8>, String> {
30        let struct_def = self
31            .structs
32            .get(&value.struct_name)
33            .ok_or_else(|| format!("Unknown struct: {}", value.struct_name))?;
34
35        let mut writer = BitWriter::new();
36        self.serialize_struct(&mut writer, struct_def, value)?;
37        Ok(writer.finish())
38    }
39
40    /// Deserialize bytes to a bitfield value.
41    pub fn deserialize(&self, struct_name: &str, data: &[u8]) -> Result<BitfieldValue, String> {
42        let struct_def = self
43            .structs
44            .get(struct_name)
45            .ok_or_else(|| format!("Unknown struct: {}", struct_name))?;
46
47        let mut reader = BitReader::new(data);
48        self.deserialize_struct(&mut reader, struct_def)
49    }
50
51    /// Serialize to a hexadecimal string.
52    pub fn to_hex(&self, value: &BitfieldValue) -> Result<String, String> {
53        let bytes = self.serialize(value)?;
54        Ok(hex::encode(bytes))
55    }
56
57    /// Deserialize from a hexadecimal string.
58    pub fn from_hex(&self, struct_name: &str, hex_str: &str) -> Result<BitfieldValue, String> {
59        let bytes = hex::decode(hex_str).map_err(|e| format!("Invalid hex string: {}", e))?;
60        self.deserialize(struct_name, &bytes)
61    }
62
63    /// Get the expected byte size for a structure.
64    pub fn byte_size(&self, struct_name: &str) -> Option<usize> {
65        let struct_def = self.structs.get(struct_name)?;
66        Some(struct_def.byte_size(&self.structs))
67    }
68
69    /// Get the expected bit size for a structure.
70    pub fn bit_size(&self, struct_name: &str) -> Option<usize> {
71        let struct_def = self.structs.get(struct_name)?;
72        Some(struct_def.bit_size(&self.structs))
73    }
74
75    /// Serialize a single structure.
76    fn serialize_struct(
77        &self,
78        writer: &mut BitWriter,
79        struct_def: &BitfieldStruct,
80        value: &BitfieldValue,
81    ) -> Result<(), String> {
82        for field in &struct_def.fields {
83            match &field.field_type {
84                FieldType::U8 => {
85                    let val = value
86                        .get_u8(&field.name)
87                        .ok_or_else(|| format!("Missing field: {}", field.name))?;
88                    writer.write_bits(val as u64, field.bits);
89                }
90                FieldType::U16 => {
91                    let val = value
92                        .get_u16(&field.name)
93                        .ok_or_else(|| format!("Missing field: {}", field.name))?;
94                    writer.write_bits(val as u64, field.bits);
95                }
96                FieldType::U32 => {
97                    let val = value
98                        .get_u32(&field.name)
99                        .ok_or_else(|| format!("Missing field: {}", field.name))?;
100                    writer.write_bits(val as u64, field.bits);
101                }
102                FieldType::U64 => {
103                    let val = value
104                        .get_u64(&field.name)
105                        .ok_or_else(|| format!("Missing field: {}", field.name))?;
106                    writer.write_bits(val, field.bits);
107                }
108                FieldType::Nested(nested_struct_name) => {
109                    let nested_value = value
110                        .get_nested(&field.name)
111                        .ok_or_else(|| format!("Missing nested field: {}", field.name))?;
112                    let nested_struct_def = self
113                        .structs
114                        .get(nested_struct_name)
115                        .ok_or_else(|| format!("Unknown nested struct: {}", nested_struct_name))?;
116                    self.serialize_struct(writer, nested_struct_def, nested_value)?;
117                }
118            }
119        }
120        Ok(())
121    }
122
123    /// Deserialize a single structure.
124    fn deserialize_struct(
125        &self,
126        reader: &mut BitReader,
127        struct_def: &BitfieldStruct,
128    ) -> Result<BitfieldValue, String> {
129        let mut result = BitfieldValue::new(&struct_def.name);
130
131        for field in &struct_def.fields {
132            match &field.field_type {
133                FieldType::U8 => {
134                    let val = reader.read_bits(field.bits)? as u8;
135                    result.set_u8(&field.name, val);
136                }
137                FieldType::U16 => {
138                    let val = reader.read_bits(field.bits)? as u16;
139                    result.set_u16(&field.name, val);
140                }
141                FieldType::U32 => {
142                    let val = reader.read_bits(field.bits)? as u32;
143                    result.set_u32(&field.name, val);
144                }
145                FieldType::U64 => {
146                    let val = reader.read_bits(field.bits)?;
147                    result.set_u64(&field.name, val);
148                }
149                FieldType::Nested(nested_struct_name) => {
150                    let nested_struct_def = self
151                        .structs
152                        .get(nested_struct_name)
153                        .ok_or_else(|| format!("Unknown nested struct: {}", nested_struct_name))?;
154                    let nested_value = self.deserialize_struct(reader, nested_struct_def)?;
155                    result.set_nested(&field.name, nested_value);
156                }
157            }
158        }
159
160        Ok(result)
161    }
162}
163
164impl Default for BitfieldSerializer {
165    fn default() -> Self {
166        Self::new()
167    }
168}
169
170#[cfg(test)]
171mod tests {
172    use super::*;
173    use crate::types::{BitfieldStruct, FieldType};
174
175    #[test]
176    fn test_simple_serialization() {
177        let mut serializer = BitfieldSerializer::new();
178
179        // Define a simple structure
180        let mut struct_def = BitfieldStruct::new("SimpleStruct");
181        struct_def.add_field("field1", 4, FieldType::U8);
182        struct_def.add_field("field2", 4, FieldType::U8);
183
184        serializer.register_struct(struct_def);
185
186        // Create a value
187        let mut value = BitfieldValue::new("SimpleStruct");
188        value.set_u8("field1", 0xA);
189        value.set_u8("field2", 0xB);
190
191        // Serialize
192        let serialized = serializer.serialize(&value).unwrap();
193        assert_eq!(serialized, vec![0xAB]); // 0xB in upper 4 bits, 0xA in lower 4 bits
194
195        // Deserialize
196        let deserialized = serializer.deserialize("SimpleStruct", &serialized).unwrap();
197        assert_eq!(deserialized.get_u8("field1"), Some(0xA));
198        assert_eq!(deserialized.get_u8("field2"), Some(0xB));
199    }
200
201    #[test]
202    fn test_nested_serialization() {
203        let mut serializer = BitfieldSerializer::new();
204
205        // Define nested structure
206        let mut inner_struct = BitfieldStruct::new("InnerStruct");
207        inner_struct.add_field("inner_field", 8, FieldType::U8);
208
209        let mut outer_struct = BitfieldStruct::new("OuterStruct");
210        outer_struct.add_field("outer_field", 4, FieldType::U8);
211        outer_struct.add_field("nested", 8, FieldType::Nested("InnerStruct".to_string()));
212
213        serializer.register_struct(inner_struct);
214        serializer.register_struct(outer_struct);
215
216        // Create nested value
217        let mut inner_value = BitfieldValue::new("InnerStruct");
218        inner_value.set_u8("inner_field", 0xFF);
219
220        let mut outer_value = BitfieldValue::new("OuterStruct");
221        outer_value.set_u8("outer_field", 0xA);
222        outer_value.set_nested("nested", inner_value);
223
224        // Serialize
225        let serialized = serializer.serialize(&outer_value).unwrap();
226
227        // Deserialize
228        let deserialized = serializer.deserialize("OuterStruct", &serialized).unwrap();
229        assert_eq!(deserialized.get_u8("outer_field"), Some(0xA));
230
231        let nested = deserialized.get_nested("nested").unwrap();
232        assert_eq!(nested.get_u8("inner_field"), Some(0xFF));
233    }
234
235    #[test]
236    fn test_hex_conversion() {
237        let mut serializer = BitfieldSerializer::new();
238
239        let mut struct_def = BitfieldStruct::new("HexStruct");
240        struct_def.add_field("field", 8, FieldType::U8);
241
242        serializer.register_struct(struct_def);
243
244        let mut value = BitfieldValue::new("HexStruct");
245        value.set_u8("field", 0xAB);
246
247        let hex = serializer.to_hex(&value).unwrap();
248        assert_eq!(hex, "ab");
249
250        let from_hex = serializer.from_hex("HexStruct", &hex).unwrap();
251        assert_eq!(from_hex.get_u8("field"), Some(0xAB));
252    }
253
254    #[test]
255    fn test_size_calculation() {
256        let mut serializer = BitfieldSerializer::new();
257
258        let mut struct_def = BitfieldStruct::new("SizeStruct");
259        struct_def.add_field("field1", 4, FieldType::U8);
260        struct_def.add_field("field2", 12, FieldType::U16);
261
262        serializer.register_struct(struct_def);
263
264        assert_eq!(serializer.bit_size("SizeStruct"), Some(16));
265        assert_eq!(serializer.byte_size("SizeStruct"), Some(2));
266    }
267
268    #[test]
269    fn test_error_handling() {
270        let serializer = BitfieldSerializer::new();
271
272        // Test unknown struct
273        let mut value = BitfieldValue::new("UnknownStruct");
274        value.set_u8("field", 42);
275
276        assert!(serializer.serialize(&value).is_err());
277        assert!(serializer.deserialize("UnknownStruct", &[0]).is_err());
278    }
279}