use crate::types::{BitfieldStruct, BitfieldValue, FieldType};
use crate::utils::{BitReader, BitWriter};
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct BitfieldSerializer {
pub structs: HashMap<String, BitfieldStruct>,
}
impl BitfieldSerializer {
pub fn new() -> Self {
Self {
structs: HashMap::new(),
}
}
pub fn register_struct(&mut self, bitfield_struct: BitfieldStruct) {
self.structs
.insert(bitfield_struct.name.clone(), bitfield_struct);
}
pub fn serialize(&self, value: &BitfieldValue) -> Result<Vec<u8>, String> {
let struct_def = self
.structs
.get(&value.struct_name)
.ok_or_else(|| format!("Unknown struct: {}", value.struct_name))?;
let mut writer = BitWriter::new();
self.serialize_struct(&mut writer, struct_def, value)?;
Ok(writer.finish())
}
pub fn deserialize(&self, struct_name: &str, data: &[u8]) -> Result<BitfieldValue, String> {
let struct_def = self
.structs
.get(struct_name)
.ok_or_else(|| format!("Unknown struct: {}", struct_name))?;
let mut reader = BitReader::new(data);
self.deserialize_struct(&mut reader, struct_def)
}
pub fn to_hex(&self, value: &BitfieldValue) -> Result<String, String> {
let bytes = self.serialize(value)?;
Ok(hex::encode(bytes))
}
pub fn from_hex(&self, struct_name: &str, hex_str: &str) -> Result<BitfieldValue, String> {
let bytes = hex::decode(hex_str).map_err(|e| format!("Invalid hex string: {}", e))?;
self.deserialize(struct_name, &bytes)
}
pub fn byte_size(&self, struct_name: &str) -> Option<usize> {
let struct_def = self.structs.get(struct_name)?;
Some(struct_def.byte_size(&self.structs))
}
pub fn bit_size(&self, struct_name: &str) -> Option<usize> {
let struct_def = self.structs.get(struct_name)?;
Some(struct_def.bit_size(&self.structs))
}
fn serialize_struct(
&self,
writer: &mut BitWriter,
struct_def: &BitfieldStruct,
value: &BitfieldValue,
) -> Result<(), String> {
for field in &struct_def.fields {
match &field.field_type {
FieldType::U8 => {
let val = value
.get_u8(&field.name)
.ok_or_else(|| format!("Missing field: {}", field.name))?;
writer.write_bits(val as u64, field.bits);
}
FieldType::U16 => {
let val = value
.get_u16(&field.name)
.ok_or_else(|| format!("Missing field: {}", field.name))?;
writer.write_bits(val as u64, field.bits);
}
FieldType::U32 => {
let val = value
.get_u32(&field.name)
.ok_or_else(|| format!("Missing field: {}", field.name))?;
writer.write_bits(val as u64, field.bits);
}
FieldType::U64 => {
let val = value
.get_u64(&field.name)
.ok_or_else(|| format!("Missing field: {}", field.name))?;
writer.write_bits(val, field.bits);
}
FieldType::Nested(nested_struct_name) => {
let nested_value = value
.get_nested(&field.name)
.ok_or_else(|| format!("Missing nested field: {}", field.name))?;
let nested_struct_def = self
.structs
.get(nested_struct_name)
.ok_or_else(|| format!("Unknown nested struct: {}", nested_struct_name))?;
self.serialize_struct(writer, nested_struct_def, nested_value)?;
}
}
}
Ok(())
}
fn deserialize_struct(
&self,
reader: &mut BitReader,
struct_def: &BitfieldStruct,
) -> Result<BitfieldValue, String> {
let mut result = BitfieldValue::new(&struct_def.name);
for field in &struct_def.fields {
match &field.field_type {
FieldType::U8 => {
let val = reader.read_bits(field.bits)? as u8;
result.set_u8(&field.name, val);
}
FieldType::U16 => {
let val = reader.read_bits(field.bits)? as u16;
result.set_u16(&field.name, val);
}
FieldType::U32 => {
let val = reader.read_bits(field.bits)? as u32;
result.set_u32(&field.name, val);
}
FieldType::U64 => {
let val = reader.read_bits(field.bits)?;
result.set_u64(&field.name, val);
}
FieldType::Nested(nested_struct_name) => {
let nested_struct_def = self
.structs
.get(nested_struct_name)
.ok_or_else(|| format!("Unknown nested struct: {}", nested_struct_name))?;
let nested_value = self.deserialize_struct(reader, nested_struct_def)?;
result.set_nested(&field.name, nested_value);
}
}
}
Ok(result)
}
}
impl Default for BitfieldSerializer {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::types::{BitfieldStruct, FieldType};
#[test]
fn test_simple_serialization() {
let mut serializer = BitfieldSerializer::new();
let mut struct_def = BitfieldStruct::new("SimpleStruct");
struct_def.add_field("field1", 4, FieldType::U8);
struct_def.add_field("field2", 4, FieldType::U8);
serializer.register_struct(struct_def);
let mut value = BitfieldValue::new("SimpleStruct");
value.set_u8("field1", 0xA);
value.set_u8("field2", 0xB);
let serialized = serializer.serialize(&value).unwrap();
assert_eq!(serialized, vec![0xAB]);
let deserialized = serializer.deserialize("SimpleStruct", &serialized).unwrap();
assert_eq!(deserialized.get_u8("field1"), Some(0xA));
assert_eq!(deserialized.get_u8("field2"), Some(0xB));
}
#[test]
fn test_nested_serialization() {
let mut serializer = BitfieldSerializer::new();
let mut inner_struct = BitfieldStruct::new("InnerStruct");
inner_struct.add_field("inner_field", 8, FieldType::U8);
let mut outer_struct = BitfieldStruct::new("OuterStruct");
outer_struct.add_field("outer_field", 4, FieldType::U8);
outer_struct.add_field("nested", 8, FieldType::Nested("InnerStruct".to_string()));
serializer.register_struct(inner_struct);
serializer.register_struct(outer_struct);
let mut inner_value = BitfieldValue::new("InnerStruct");
inner_value.set_u8("inner_field", 0xFF);
let mut outer_value = BitfieldValue::new("OuterStruct");
outer_value.set_u8("outer_field", 0xA);
outer_value.set_nested("nested", inner_value);
let serialized = serializer.serialize(&outer_value).unwrap();
let deserialized = serializer.deserialize("OuterStruct", &serialized).unwrap();
assert_eq!(deserialized.get_u8("outer_field"), Some(0xA));
let nested = deserialized.get_nested("nested").unwrap();
assert_eq!(nested.get_u8("inner_field"), Some(0xFF));
}
#[test]
fn test_hex_conversion() {
let mut serializer = BitfieldSerializer::new();
let mut struct_def = BitfieldStruct::new("HexStruct");
struct_def.add_field("field", 8, FieldType::U8);
serializer.register_struct(struct_def);
let mut value = BitfieldValue::new("HexStruct");
value.set_u8("field", 0xAB);
let hex = serializer.to_hex(&value).unwrap();
assert_eq!(hex, "ab");
let from_hex = serializer.from_hex("HexStruct", &hex).unwrap();
assert_eq!(from_hex.get_u8("field"), Some(0xAB));
}
#[test]
fn test_size_calculation() {
let mut serializer = BitfieldSerializer::new();
let mut struct_def = BitfieldStruct::new("SizeStruct");
struct_def.add_field("field1", 4, FieldType::U8);
struct_def.add_field("field2", 12, FieldType::U16);
serializer.register_struct(struct_def);
assert_eq!(serializer.bit_size("SizeStruct"), Some(16));
assert_eq!(serializer.byte_size("SizeStruct"), Some(2));
}
#[test]
fn test_error_handling() {
let serializer = BitfieldSerializer::new();
let mut value = BitfieldValue::new("UnknownStruct");
value.set_u8("field", 42);
assert!(serializer.serialize(&value).is_err());
assert!(serializer.deserialize("UnknownStruct", &[0]).is_err());
}
}