rust_bitfield_serializer/
macros.rs

1// Macros for defining bitfield structures.
2#![allow(unused_imports)]
3#![allow(unused_assignments)]
4#![allow(dead_code)]
5
6/// Macro for defining bitfield structures with automatic serialization support.
7///
8/// # Usage
9///
10/// ```
11/// use rust_bitfield_serializer::*;
12///
13/// bitfield! {
14///     struct MyBitfield {
15///         field1: u8, 4,
16///         field2: u8, 4,
17///     }
18/// }
19/// ```
20///
21/// # Examples
22///
23/// ```
24/// use rust_bitfield_serializer::*;
25/// bitfield! {
26///     struct MyBitfield {
27///         field1: u8, 4,
28///         field2: u8, 4,
29///     }
30/// }
31/// let mut bf = MyBitfield::new();
32/// bf.field1 = 0xA;
33/// bf.field2 = 0xB;
34/// let bytes = bf.serialize();
35/// assert_eq!(bytes, vec![0xAB]);
36/// let bf2 = MyBitfield::deserialize(&bytes).unwrap();
37/// assert_eq!(bf2.field1, 0xA);
38/// assert_eq!(bf2.field2, 0xB);
39/// ```
40///
41/// Nested structures example:
42///
43/// ```
44/// use rust_bitfield_serializer::*;
45/// bitfield! {
46///     struct NestedHeader {
47///         version: u8, 4,
48///         flags: u8, 4,
49///     }
50///
51///     struct NestedPacket {
52///         header: NestedHeader,
53///         payload_len: u16, 12,
54///         checksum: u8, 8,
55///     }
56/// }
57/// let mut p = NestedPacket::new();
58/// p.header.version = 2;
59/// p.header.flags = 0xF;
60/// p.payload_len = 0xABC;
61/// p.checksum = 0x1;
62/// let bytes = p.serialize();
63/// let p2 = NestedPacket::deserialize(&bytes).unwrap();
64/// assert_eq!(p2.header.version, 2);
65/// assert_eq!(p2.header.flags, 0xF);
66/// assert_eq!(p2.payload_len, 0xABC);
67/// assert_eq!(p2.checksum, 0x1);
68/// ```
69///
70/// This creates a struct `MyBitfield` with fields that can be accessed directly,
71/// along with serialization and deserialization capabilities.
72///
73/// # Multiple Structures
74///
75/// You can define multiple structures in a single macro invocation:
76///
77/// ```
78/// use rust_bitfield_serializer::*;
79/// bitfield! {
80///     struct Header {
81///         version: u8, 4,
82///         flags: u8, 4,
83///     }
84///
85///     struct Packet {
86///         header: Header,
87///         payload_len: u16, 12,
88///         checksum: u8, 8,
89///     }
90/// }
91/// ```
92///
93/// # Nested Structures
94///
95/// Bitfield structures can contain other bitfield structures as fields.
96/// When no bit count is specified, the entire nested structure is used.
97#[macro_export]
98macro_rules! bitfield {
99    // Multiple structures
100    (
101        $(
102            struct $name:ident {
103                $(
104                    $field_name:ident: $field_type:ty $(, $bits:literal)?
105                ),* $(,)?
106            }
107        )+
108    ) => {
109        $(
110            bitfield!(@single $name { $($field_name: $field_type $(, $bits)?),* });
111        )+
112    };
113
114    // Single structure
115    (
116        struct $name:ident {
117            $(
118                $field_name:ident: $field_type:ty $(, $bits:literal)?
119            ),* $(,)?
120        }
121    ) => {
122        bitfield!(@single $name { $($field_name: $field_type $(, $bits)?),* });
123    };
124
125    // Generate single structure implementation
126    (@single $name:ident { $($field_name:ident: $field_type:ty $(, $bits:literal)?),* }) => {
127        #[derive(Debug, Clone, PartialEq)]
128        pub struct $name {
129            $(
130                pub $field_name: bitfield!(@field_type $field_type $(, $bits)?),
131            )*
132            _internal_data: Vec<u8>,
133        }
134
135        impl $name {
136            /// Create a new instance with default values.
137            pub fn new() -> Self {
138                Self {
139                    $(
140                        $field_name: Default::default(),
141                    )*
142                    _internal_data: vec![0; Self::byte_size()],
143                }
144            }
145
146            /// Synchronize field values to internal data for serialization.
147            pub fn sync_to_data(&mut self) {
148                self._internal_data = vec![0; Self::byte_size()];
149                let mut current_bit = 0;
150                $(
151                    bitfield!(@write_field_to_data self, $field_name, $field_type, current_bit $(, $bits)?);
152                )*
153            }
154
155            /// Synchronize internal data to field values after deserialization.
156            pub fn sync_from_data(&mut self) {
157                let mut current_bit = 0;
158                $(
159                    bitfield!(@read_field_from_data self, $field_name, $field_type, current_bit $(, $bits)?);
160                )*
161            }
162
163            /// Get the bit size of a specific field.
164            pub fn field_bit_size(field_name: &str) -> Option<usize> {
165                match field_name {
166                    $(
167                        stringify!($field_name) => Some(bitfield!(@size $field_type $(, $bits)?)),
168                    )*
169                    _ => None,
170                }
171            }
172
173            /// Get the bit offset of a specific field.
174            pub fn field_bit_offset(field_name: &str) -> Option<usize> {
175                let mut current_bit = 0;
176                $(
177                    if field_name == stringify!($field_name) {
178                        return Some(current_bit);
179                    }
180                    current_bit += bitfield!(@size $field_type $(, $bits)?);
181                )*
182                None
183            }
184
185            /// Read bits from data at a specific position.
186            fn read_bits_from_data(data: &[u8], start_bit: usize, num_bits: usize) -> u64 {
187                $crate::utils::BitReader::read_bits_at(data, start_bit, num_bits)
188            }
189
190            /// Write bits to data at a specific position.
191            fn write_bits_to_data(data: &mut [u8], start_bit: usize, value: u64, num_bits: usize) {
192                $crate::utils::BitWriter::write_bits_to(data, start_bit, value, num_bits);
193            }
194        }
195
196        impl $crate::traits::BitfieldSize for $name {
197            fn bit_size() -> usize {
198                0 $(+ bitfield!(@size $field_type $(, $bits)?))*
199            }
200        }
201
202        impl $crate::traits::BitfieldSerialize for $name {
203            fn serialize(&self) -> Vec<u8> {
204                let mut instance = self.clone();
205                instance.sync_to_data();
206                instance._internal_data
207            }
208
209            fn deserialize(data: &[u8]) -> Result<Self, String> {
210                if data.len() != Self::byte_size() {
211                    return Err(format!(
212                        "Data size mismatch: expected {} bytes, got {}",
213                        Self::byte_size(),
214                        data.len()
215                    ));
216                }
217                let mut instance = Self::new();
218                instance._internal_data = data.to_vec();
219                instance.sync_from_data();
220                Ok(instance)
221            }
222        }
223
224        impl Default for $name {
225            fn default() -> Self {
226                Self::new()
227            }
228        }
229    };
230
231    // Determine field type
232    (@field_type $field_type:ty, $bits:literal) => {
233        $field_type
234    };
235
236    (@field_type $field_type:ty) => {
237        $field_type
238    };
239
240    // Write field value to internal data
241    (@write_field_to_data $self:ident, $field_name:ident, $field_type:ty, $current_bit:ident, $bits:literal) => {
242        {
243            let value = $self.$field_name as u64;
244            Self::write_bits_to_data(&mut $self._internal_data, $current_bit, value, $bits);
245            $current_bit += $bits;
246        }
247    };
248
249    (@write_field_to_data $self:ident, $field_name:ident, $field_type:ty, $current_bit:ident) => {
250        {
251            let serialized = $self.$field_name.serialize();
252            let bit_size = <$field_type>::bit_size();
253            for (i, &byte) in serialized.iter().enumerate() {
254                let byte_start_bit = $current_bit + i * 8;
255                let remaining_bits = bit_size.saturating_sub(i * 8).min(8);
256                Self::write_bits_to_data(&mut $self._internal_data, byte_start_bit, byte as u64, remaining_bits);
257            }
258            $current_bit += bit_size;
259        }
260    };
261
262    // Read field value from internal data
263    (@read_field_from_data $self:ident, $field_name:ident, $field_type:ty, $current_bit:ident, $bits:literal) => {
264        {
265            let value = Self::read_bits_from_data(&$self._internal_data, $current_bit, $bits);
266            $self.$field_name = value as $field_type;
267            $current_bit += $bits;
268        }
269    };
270
271    (@read_field_from_data $self:ident, $field_name:ident, $field_type:ty, $current_bit:ident) => {
272        {
273            let bit_size = <$field_type>::bit_size();
274            let byte_size = bit_size.div_ceil(8);
275            let mut field_data = vec![0u8; byte_size];
276
277            for i in 0..byte_size {
278                let byte_start_bit = $current_bit + i * 8;
279                let remaining_bits = bit_size.saturating_sub(i * 8).min(8);
280                let byte_value = Self::read_bits_from_data(&$self._internal_data, byte_start_bit, remaining_bits);
281                field_data[i] = byte_value as u8;
282            }
283
284            match <$field_type>::deserialize(&field_data) {
285                Ok(value) => $self.$field_name = value,
286                Err(_) => $self.$field_name = Default::default(),
287            }
288            $current_bit += bit_size;
289        }
290    };
291
292    // Calculate field size
293    (@size $field_type:ty, $bits:literal) => {
294        $bits
295    };
296
297    (@size $field_type:ty) => {
298        <$field_type>::bit_size()
299    };
300}
301
302#[cfg(test)]
303mod tests {
304    use super::*;
305    use crate::traits::{BitfieldSerialize, BitfieldSize};
306
307    bitfield! {
308        struct TestStruct {
309            field1: u8, 4,
310            field2: u8, 4,
311        }
312    }
313
314    bitfield! {
315        struct SimpleHeader {
316            version: u8, 4,
317            flags: u8, 4,
318        }
319
320        struct ComplexPacket {
321            header: SimpleHeader,
322            payload_len: u16, 12,
323            checksum: u8, 8,
324        }
325    }
326
327    #[test]
328    fn test_basic_bitfield() {
329        let mut test_struct = TestStruct::new();
330        test_struct.field1 = 0xA;
331        test_struct.field2 = 0xB;
332
333        assert_eq!(TestStruct::bit_size(), 8);
334        assert_eq!(TestStruct::byte_size(), 1);
335
336        let serialized = test_struct.serialize();
337        assert_eq!(serialized.len(), 1);
338
339        let deserialized = TestStruct::deserialize(&serialized).unwrap();
340        assert_eq!(deserialized.field1, 0xA);
341        assert_eq!(deserialized.field2, 0xB);
342    }
343
344    #[test]
345    fn test_nested_bitfield() {
346        let mut packet = ComplexPacket::new();
347        packet.header.version = 2;
348        packet.header.flags = 0xF;
349        packet.payload_len = 1024;
350        packet.checksum = 0xFF;
351
352        let serialized = packet.serialize();
353        let deserialized = ComplexPacket::deserialize(&serialized).unwrap();
354
355        assert_eq!(deserialized.header.version, 2);
356        assert_eq!(deserialized.header.flags, 0xF);
357        assert_eq!(deserialized.payload_len, 1024);
358        assert_eq!(deserialized.checksum, 0xFF);
359    }
360
361    #[test]
362    fn test_field_metadata() {
363        assert_eq!(TestStruct::field_bit_size("field1"), Some(4));
364        assert_eq!(TestStruct::field_bit_size("field2"), Some(4));
365        assert_eq!(TestStruct::field_bit_size("nonexistent"), None);
366
367        assert_eq!(TestStruct::field_bit_offset("field1"), Some(0));
368        assert_eq!(TestStruct::field_bit_offset("field2"), Some(4));
369        assert_eq!(TestStruct::field_bit_offset("nonexistent"), None);
370    }
371
372    #[test]
373    fn test_hex_serialization() {
374        let mut test_struct = TestStruct::new();
375        test_struct.field1 = 0xA;
376        test_struct.field2 = 0xB;
377
378        let hex = test_struct.to_hex();
379        let from_hex = TestStruct::from_hex(&hex).unwrap();
380
381        assert_eq!(from_hex.field1, 0xA);
382        assert_eq!(from_hex.field2, 0xB);
383    }
384}