rust_bitfield_serializer/
traits.rs

1//! Traits for bitfield serialization and sizing.
2extern crate hex;
3/// Trait for serializing and deserializing bitfield structures.
4pub trait BitfieldSerialize {
5    /// Serialize the bitfield to a byte vector.
6    fn serialize(&self) -> Vec<u8>;
7
8    /// Deserialize a bitfield from a byte slice.
9    fn deserialize(data: &[u8]) -> Result<Self, String>
10    where
11        Self: Sized;
12
13    /// Serialize to a hexadecimal string.
14    fn to_hex(&self) -> String {
15        hex::encode(self.serialize())
16    }
17
18    /// Deserialize from a hexadecimal string.
19    fn from_hex(hex_str: &str) -> Result<Self, String>
20    where
21        Self: Sized,
22    {
23        let bytes = hex::decode(hex_str).map_err(|e| format!("Invalid hex string: {}", e))?;
24        Self::deserialize(&bytes)
25    }
26}
27
28/// Trait for getting the size of a bitfield structure.
29pub trait BitfieldSize {
30    /// Return the total number of bits in the bitfield.
31    fn bit_size() -> usize;
32
33    /// Return the number of bytes needed to store the bitfield (rounded up).
34    fn byte_size() -> usize {
35        Self::bit_size().div_ceil(8)
36    }
37}
38
39// Implement BitfieldSize for primitive types
40impl BitfieldSize for u8 {
41    fn bit_size() -> usize {
42        8
43    }
44}
45
46impl BitfieldSize for u16 {
47    fn bit_size() -> usize {
48        16
49    }
50}
51
52impl BitfieldSize for u32 {
53    fn bit_size() -> usize {
54        32
55    }
56}
57
58impl BitfieldSize for u64 {
59    fn bit_size() -> usize {
60        64
61    }
62}
63
64// Implement BitfieldSerialize for primitive types
65impl BitfieldSerialize for u8 {
66    fn serialize(&self) -> Vec<u8> {
67        vec![*self]
68    }
69
70    fn deserialize(data: &[u8]) -> Result<Self, String> {
71        if data.is_empty() {
72            return Err("Empty data".to_string());
73        }
74        Ok(data[0])
75    }
76}
77
78impl BitfieldSerialize for u16 {
79    fn serialize(&self) -> Vec<u8> {
80        self.to_le_bytes().to_vec()
81    }
82
83    fn deserialize(data: &[u8]) -> Result<Self, String> {
84        if data.len() < 2 {
85            return Err("Insufficient data for u16".to_string());
86        }
87        Ok(u16::from_le_bytes([data[0], data[1]]))
88    }
89}
90
91impl BitfieldSerialize for u32 {
92    fn serialize(&self) -> Vec<u8> {
93        self.to_le_bytes().to_vec()
94    }
95
96    fn deserialize(data: &[u8]) -> Result<Self, String> {
97        if data.len() < 4 {
98            return Err("Insufficient data for u32".to_string());
99        }
100        Ok(u32::from_le_bytes([data[0], data[1], data[2], data[3]]))
101    }
102}
103
104impl BitfieldSerialize for u64 {
105    fn serialize(&self) -> Vec<u8> {
106        self.to_le_bytes().to_vec()
107    }
108
109    fn deserialize(data: &[u8]) -> Result<Self, String> {
110        if data.len() < 8 {
111            return Err("Insufficient data for u64".to_string());
112        }
113        Ok(u64::from_le_bytes([
114            data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
115        ]))
116    }
117}
118
119#[cfg(test)]
120mod tests {
121    use super::*;
122
123    #[test]
124    fn test_u8_serialize() {
125        let value = 42u8;
126        let serialized = value.serialize();
127        assert_eq!(serialized, vec![42]);
128        assert_eq!(u8::deserialize(&serialized).unwrap(), 42);
129    }
130
131    #[test]
132    fn test_u16_serialize() {
133        let value = 0x1234u16;
134        let serialized = value.serialize();
135        assert_eq!(serialized, vec![0x34, 0x12]); // Little endian
136        assert_eq!(u16::deserialize(&serialized).unwrap(), 0x1234);
137    }
138
139    #[test]
140    fn test_hex_conversion() {
141        let value = 0xABu8;
142        let hex = value.to_hex();
143        assert_eq!(hex, "ab");
144        assert_eq!(u8::from_hex(&hex).unwrap(), 0xAB);
145    }
146
147    #[test]
148    fn test_bit_sizes() {
149        assert_eq!(u8::bit_size(), 8);
150        assert_eq!(u16::bit_size(), 16);
151        assert_eq!(u32::bit_size(), 32);
152        assert_eq!(u64::bit_size(), 64);
153    }
154
155    #[test]
156    fn test_byte_sizes() {
157        assert_eq!(u8::byte_size(), 1);
158        assert_eq!(u16::byte_size(), 2);
159        assert_eq!(u32::byte_size(), 4);
160        assert_eq!(u64::byte_size(), 8);
161    }
162}