byte_struct/
lib.rs

1//! # Byte Struct
2//!
3//! Pack and unpack structure as raw bytes with packed or bit field layout.
4//!
5//! ## Example
6//! ```
7//! use byte_struct::*;
8//!
9//! bitfields!(
10//!     #[derive(PartialEq, Debug)]
11//!     GIFColorTableInfo: u8 {
12//!         global_color_table_flag: 1,
13//!         color_resolution: 3,
14//!         sort_flag: 1,
15//!         global_color_table_size: 3,
16//!     }
17//! );
18//!
19//! #[derive(ByteStruct, PartialEq, Debug)]
20//! #[byte_struct_le]
21//! struct GIFLogicalScreenDescriptor {
22//!     width: u16,
23//!     height: u16,
24//!     color_table_info: GIFColorTableInfo,
25//!     background_color_index: u8,
26//!     pixel_aspect_ratio: u8,
27//! }
28//!
29//! fn example() {
30//!     assert_eq!(GIFLogicalScreenDescriptor::BYTE_LEN, 7);
31//!     let raw_descriptor = [0x03, 0x00, 0x05, 0x00, 0xF7, 0x00, 0x00];
32//!     let descriptor = GIFLogicalScreenDescriptor::read_bytes(&raw_descriptor[..]);
33//!     assert_eq!(descriptor, GIFLogicalScreenDescriptor{
34//!         width: 3,
35//!         height: 5,
36//!         color_table_info: GIFColorTableInfo {
37//!             global_color_table_flag: 1,
38//!             color_resolution: 3,
39//!             sort_flag: 1,
40//!             global_color_table_size: 7,
41//!         },
42//!         background_color_index: 0,
43//!         pixel_aspect_ratio: 0,
44//!     });
45//!     let mut raw_another = [0; GIFLogicalScreenDescriptor::BYTE_LEN];
46//!     descriptor.write_bytes(&mut raw_another[..]);
47//!     assert_eq!(raw_descriptor, raw_another);
48//! }
49//! ```
50
51#![no_std]
52
53pub use byte_struct_derive::{ByteStruct, ByteStructBE, ByteStructLE};
54
55/// A type that can be packed into or unpacked from fixed-size bytes, but the method is unknown yet.
56pub trait ByteStructLen {
57    /// The length of the packed bytes of this type
58    const BYTE_LEN: usize;
59}
60
61/// A data structure that can be packed into or unpacked from raw bytes.
62///
63/// This trait can be derived by
64/// [`#[derive(ByteStruct)]`](https://docs.rs/byte_struct_derive/*/byte_struct_derive/derive.ByteStruct.html).
65///
66/// One can implement this trait for custom types in order to pack or unpack an object in a special way.
67pub trait ByteStruct: ByteStructLen {
68    /// Packs the struct into raw bytes and write to a slice
69    fn write_bytes(&self, bytes: &mut [u8]);
70
71    /// Unpacks raw bytes from a slice into a new struct
72    fn read_bytes(bytes: &[u8]) -> Self;
73}
74
75/// A type that can be packed into or unpacked from raw bytes under given default byte order.
76///
77/// This trait is implemented for most numeric primitive types,
78/// except for `bool`, `char`, `isize` and `usize`. This is also implemented for array types
79/// whose element type implements `ByteStructUnspecifiedByteOrder`.
80///
81/// This trait is automatically implemented for all types that implements [`ByteStruct`].
82/// In this case, all members of `ByteStructUnspecifiedByteOrder` are direct wrappers of [`ByteStruct`] members.
83///
84/// Members in this trait are meant to be called by byte_struct internal only.
85/// They do not do what one might expect:
86/// the byte orders specified in `read_bytes_default_*` / `write_bytes_default_*` functions
87/// are only **default byte orders**.
88/// The default byte order is only respected when the type itself does not carry byte order specification
89/// (e.g. primitive types).
90/// In contrast, since [`ByteStruct`] types always have fixed packing method,
91/// the default byte order has no effect on them, and the three versions of read / write functions for them,
92/// `_default_le`, `_default_be` and no-spec from [`ByteStruct`], behave exactly the same.
93///
94/// One can implement this trait for custom types in order to pack or unpack an object in a special way,
95/// but only when the said type changes its packing method depending on the default byte order.
96/// An example for this is a custom fixed-size large integer type.
97/// If the packing method is independent from the default byte order, please implement [`ByteStruct`] instead.
98///
99/// [`ByteStruct`]: trait.ByteStruct.html
100pub trait ByteStructUnspecifiedByteOrder: ByteStructLen {
101    /// Packs the object into raw bytes with little-endian as the default byte order
102    fn write_bytes_default_le(&self, bytes: &mut [u8]);
103
104    /// Unpacks raw bytes into a new object with little-endian as the default byte order
105    fn read_bytes_default_le(bytes: &[u8]) -> Self;
106
107    /// Packs the object into raw bytes with big-endian as the default byte order
108    fn write_bytes_default_be(&self, bytes: &mut [u8]);
109
110    /// Unpacks raw bytes into a new object with big-endian as the default byte order
111    fn read_bytes_default_be(bytes: &[u8]) -> Self;
112}
113
114impl<T: ByteStruct> ByteStructUnspecifiedByteOrder for T {
115    /// A wrapper of [`ByteStruct::write_bytes`](trait.ByteStruct.html#tymethod.write_bytes)
116    fn write_bytes_default_le(&self, bytes: &mut [u8]) {
117        self.write_bytes(bytes);
118    }
119
120    /// A wrapper of [`ByteStruct::read_bytes`](trait.ByteStruct.html#tymethod.read_bytes)
121    fn read_bytes_default_le(bytes: &[u8]) -> Self {
122        Self::read_bytes(bytes)
123    }
124
125    /// A wrapper of [`ByteStruct::write_bytes`](trait.ByteStruct.html#tymethod.write_bytes)
126    fn write_bytes_default_be(&self, bytes: &mut [u8]) {
127        self.write_bytes(bytes);
128    }
129
130    /// A wrapper of [`ByteStruct::read_bytes`](trait.ByteStruct.html#tymethod.read_bytes)
131    fn read_bytes_default_be(bytes: &[u8]) -> Self {
132        Self::read_bytes(bytes)
133    }
134}
135
136impl ByteStructLen for u8 {
137    const BYTE_LEN: usize = 1;
138}
139
140impl ByteStructUnspecifiedByteOrder for u8 {
141    fn write_bytes_default_le(&self, bytes: &mut [u8]) {
142        bytes.copy_from_slice(&self.to_le_bytes()[..]);
143    }
144    fn read_bytes_default_le(bytes: &[u8]) -> Self {
145        u8::from_le_bytes([bytes[0]])
146    }
147    fn write_bytes_default_be(&self, bytes: &mut [u8]) {
148        bytes.copy_from_slice(&self.to_be_bytes()[..]);
149    }
150    fn read_bytes_default_be(bytes: &[u8]) -> Self {
151        u8::from_be_bytes([bytes[0]])
152    }
153}
154
155impl ByteStructLen for i8 {
156    const BYTE_LEN: usize = 1;
157}
158
159impl ByteStructUnspecifiedByteOrder for i8 {
160    fn write_bytes_default_le(&self, bytes: &mut [u8]) {
161        bytes.copy_from_slice(&self.to_le_bytes()[..]);
162    }
163    fn read_bytes_default_le(bytes: &[u8]) -> Self {
164        i8::from_le_bytes([bytes[0]])
165    }
166    fn write_bytes_default_be(&self, bytes: &mut [u8]) {
167        bytes.copy_from_slice(&self.to_be_bytes()[..]);
168    }
169    fn read_bytes_default_be(bytes: &[u8]) -> Self {
170        i8::from_be_bytes([bytes[0]])
171    }
172}
173
174impl ByteStructLen for u16 {
175    const BYTE_LEN: usize = 2;
176}
177
178impl ByteStructUnspecifiedByteOrder for u16 {
179    fn write_bytes_default_le(&self, bytes: &mut [u8]) {
180        bytes.copy_from_slice(&self.to_le_bytes()[..]);
181    }
182    fn read_bytes_default_le(bytes: &[u8]) -> Self {
183        u16::from_le_bytes([bytes[0], bytes[1]])
184    }
185    fn write_bytes_default_be(&self, bytes: &mut [u8]) {
186        bytes.copy_from_slice(&self.to_be_bytes()[..]);
187    }
188    fn read_bytes_default_be(bytes: &[u8]) -> Self {
189        u16::from_be_bytes([bytes[0], bytes[1]])
190    }
191}
192
193impl ByteStructLen for i16 {
194    const BYTE_LEN: usize = 2;
195}
196
197impl ByteStructUnspecifiedByteOrder for i16 {
198    fn write_bytes_default_le(&self, bytes: &mut [u8]) {
199        bytes.copy_from_slice(&self.to_le_bytes()[..]);
200    }
201    fn read_bytes_default_le(bytes: &[u8]) -> Self {
202        i16::from_le_bytes([bytes[0], bytes[1]])
203    }
204    fn write_bytes_default_be(&self, bytes: &mut [u8]) {
205        bytes.copy_from_slice(&self.to_be_bytes()[..]);
206    }
207    fn read_bytes_default_be(bytes: &[u8]) -> Self {
208        i16::from_be_bytes([bytes[0], bytes[1]])
209    }
210}
211
212impl ByteStructLen for u32 {
213    const BYTE_LEN: usize = 4;
214}
215
216impl ByteStructUnspecifiedByteOrder for u32 {
217    fn write_bytes_default_le(&self, bytes: &mut [u8]) {
218        bytes.copy_from_slice(&self.to_le_bytes()[..]);
219    }
220    fn read_bytes_default_le(bytes: &[u8]) -> Self {
221        u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])
222    }
223    fn write_bytes_default_be(&self, bytes: &mut [u8]) {
224        bytes.copy_from_slice(&self.to_be_bytes()[..]);
225    }
226    fn read_bytes_default_be(bytes: &[u8]) -> Self {
227        u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])
228    }
229}
230
231impl ByteStructLen for i32 {
232    const BYTE_LEN: usize = 4;
233}
234
235impl ByteStructUnspecifiedByteOrder for i32 {
236    fn write_bytes_default_le(&self, bytes: &mut [u8]) {
237        bytes.copy_from_slice(&self.to_le_bytes()[..]);
238    }
239    fn read_bytes_default_le(bytes: &[u8]) -> Self {
240        i32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])
241    }
242    fn write_bytes_default_be(&self, bytes: &mut [u8]) {
243        bytes.copy_from_slice(&self.to_be_bytes()[..]);
244    }
245    fn read_bytes_default_be(bytes: &[u8]) -> Self {
246        i32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]])
247    }
248}
249
250impl ByteStructLen for u64 {
251    const BYTE_LEN: usize = 8;
252}
253
254impl ByteStructUnspecifiedByteOrder for u64 {
255    fn write_bytes_default_le(&self, bytes: &mut [u8]) {
256        bytes.copy_from_slice(&self.to_le_bytes()[..]);
257    }
258    fn read_bytes_default_le(bytes: &[u8]) -> Self {
259        u64::from_le_bytes([
260            bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
261        ])
262    }
263    fn write_bytes_default_be(&self, bytes: &mut [u8]) {
264        bytes.copy_from_slice(&self.to_be_bytes()[..]);
265    }
266    fn read_bytes_default_be(bytes: &[u8]) -> Self {
267        u64::from_be_bytes([
268            bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
269        ])
270    }
271}
272
273impl ByteStructLen for i64 {
274    const BYTE_LEN: usize = 8;
275}
276
277impl ByteStructUnspecifiedByteOrder for i64 {
278    fn write_bytes_default_le(&self, bytes: &mut [u8]) {
279        bytes.copy_from_slice(&self.to_le_bytes()[..]);
280    }
281    fn read_bytes_default_le(bytes: &[u8]) -> Self {
282        i64::from_le_bytes([
283            bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
284        ])
285    }
286    fn write_bytes_default_be(&self, bytes: &mut [u8]) {
287        bytes.copy_from_slice(&self.to_be_bytes()[..]);
288    }
289    fn read_bytes_default_be(bytes: &[u8]) -> Self {
290        i64::from_be_bytes([
291            bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
292        ])
293    }
294}
295
296impl ByteStructLen for u128 {
297    const BYTE_LEN: usize = 16;
298}
299
300impl ByteStructUnspecifiedByteOrder for u128 {
301    fn write_bytes_default_le(&self, bytes: &mut [u8]) {
302        bytes.copy_from_slice(&self.to_le_bytes()[..]);
303    }
304    fn read_bytes_default_le(bytes: &[u8]) -> Self {
305        u128::from_le_bytes([
306            bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
307            bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
308        ])
309    }
310    fn write_bytes_default_be(&self, bytes: &mut [u8]) {
311        bytes.copy_from_slice(&self.to_be_bytes()[..]);
312    }
313    fn read_bytes_default_be(bytes: &[u8]) -> Self {
314        u128::from_be_bytes([
315            bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
316            bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
317        ])
318    }
319}
320
321impl ByteStructLen for i128 {
322    const BYTE_LEN: usize = 16;
323}
324
325impl ByteStructUnspecifiedByteOrder for i128 {
326    fn write_bytes_default_le(&self, bytes: &mut [u8]) {
327        bytes.copy_from_slice(&self.to_le_bytes()[..]);
328    }
329    fn read_bytes_default_le(bytes: &[u8]) -> Self {
330        i128::from_le_bytes([
331            bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
332            bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
333        ])
334    }
335    fn write_bytes_default_be(&self, bytes: &mut [u8]) {
336        bytes.copy_from_slice(&self.to_be_bytes()[..]);
337    }
338    fn read_bytes_default_be(bytes: &[u8]) -> Self {
339        i128::from_be_bytes([
340            bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
341            bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
342        ])
343    }
344}
345
346impl ByteStructLen for f32 {
347    const BYTE_LEN: usize = 4;
348}
349
350impl ByteStructUnspecifiedByteOrder for f32 {
351    fn write_bytes_default_le(&self, bytes: &mut [u8]) {
352        bytes.copy_from_slice(&self.to_bits().to_le_bytes()[..]);
353    }
354    fn read_bytes_default_le(bytes: &[u8]) -> Self {
355        f32::from_bits(u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
356    }
357    fn write_bytes_default_be(&self, bytes: &mut [u8]) {
358        bytes.copy_from_slice(&self.to_bits().to_be_bytes()[..]);
359    }
360    fn read_bytes_default_be(bytes: &[u8]) -> Self {
361        f32::from_bits(u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]))
362    }
363}
364
365impl ByteStructLen for f64 {
366    const BYTE_LEN: usize = 8;
367}
368
369impl ByteStructUnspecifiedByteOrder for f64 {
370    fn write_bytes_default_le(&self, bytes: &mut [u8]) {
371        bytes.copy_from_slice(&self.to_bits().to_le_bytes()[..]);
372    }
373    fn read_bytes_default_le(bytes: &[u8]) -> Self {
374        f64::from_bits(u64::from_le_bytes([
375            bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
376        ]))
377    }
378    fn write_bytes_default_be(&self, bytes: &mut [u8]) {
379        bytes.copy_from_slice(&self.to_bits().to_be_bytes()[..]);
380    }
381    fn read_bytes_default_be(bytes: &[u8]) -> Self {
382        f64::from_bits(u64::from_le_bytes([
383            bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
384        ]))
385    }
386}
387
388impl<T: ByteStructLen, const N: usize> ByteStructLen for [T; N] {
389    const BYTE_LEN: usize = N * T::BYTE_LEN;
390}
391
392impl<T: ByteStructUnspecifiedByteOrder, const N: usize> ByteStructUnspecifiedByteOrder for [T; N] {
393    fn write_bytes_default_le(&self, bytes: &mut [u8]) {
394        let mut pos = 0;
395        let len = T::BYTE_LEN;
396        for element in self {
397            element.write_bytes_default_le(&mut bytes[pos..pos + len]);
398            pos += len;
399        }
400    }
401    fn read_bytes_default_le(bytes: &[u8]) -> Self {
402        let len = T::BYTE_LEN;
403        core::array::from_fn(|i| <T>::read_bytes_default_le(&bytes[i * len..(i + 1) * len]))
404    }
405    fn write_bytes_default_be(&self, bytes: &mut [u8]) {
406        let mut pos = 0;
407        let len = T::BYTE_LEN;
408        for element in self {
409            element.write_bytes_default_be(&mut bytes[pos..pos + len]);
410            pos += len;
411        }
412    }
413    fn read_bytes_default_be(bytes: &[u8]) -> Self {
414        let len = T::BYTE_LEN;
415        core::array::from_fn(|i| <T>::read_bytes_default_be(&bytes[i * len..(i + 1) * len]))
416    }
417}
418
419/// Generates a structure that implements [`ByteStructUnspecifiedByteOrder`] with bit field semantics.
420///
421/// The bit fields are packed to / unpacked from the base integer type,
422/// which is then packed / unpacked using the primitive type's [`ByteStructUnspecifiedByteOrder`] implementation.
423/// Therefore, the byte order of bit fields is unspecified internally, and is only specified
424/// by the parent structure that derives [`ByteStruct`](trait.ByteStruct.html), just like all primitive
425/// types.
426///
427/// Note that the memory representation of the generated structure during runtime is NOT in bit field layout.
428/// This macro only provides conversion method between the plain structure and the bit-field-packed bytes.
429///
430/// [`ByteStructUnspecifiedByteOrder`]: trait.ByteStructUnspecifiedByteOrder.html
431///
432/// # Example
433/// ```ignore
434/// bitfields!(
435///     // Specifies the struct name and the base type.
436///     // The base type must be one of unsigned integer types.
437///     // Attributes and visibility specifier can be attached before the struct name.
438///     #[derive(PartialEq, Debug)]
439///     SampleBitField: u16 {
440///         // Specifies members and bit length from the least significant bit to the most.
441///         // The bit layout is assumed packed, and paddings must be explicitly specified.
442///         // The sum of bit length of all fields must equal the bit length of the base type.
443///         // Attributes and visibility specifier can be attached before the field name.
444///
445///         // This creates bit field structure in the following layout:
446///         //
447///         // | MSB                                                        LSB |
448///         // | 15| 14| 13| 12| 11| 10| 9 | 8 | 7 |  6 | 5 | 4 | 3 | 2 | 1 | 0 |
449///         // |     z     |pad|               y                |       x       |
450///         //
451///         pub x: 4,
452///         pub y: 8,
453///         padding: 1,
454///         pub z: 3,
455///     }
456/// );
457///
458/// // The macro above generates the structure below.
459///
460/// #[derive(PartialEq, Debug)]
461/// struct SampleBitField {
462///     pub x: u16,
463///     pub y: u16,
464///     padding: u16,
465///     pub z: u16,
466/// }
467///
468/// impl ByteStructUnspecifiedByteOrder for SampleBitField {
469///     ...
470/// }
471/// ```
472#[macro_export]
473macro_rules! bitfields{
474    (
475        $(#[$outer:meta])*
476        $visibility:vis $name:ident : $base:ty {
477            $(
478                $(#[$inner:ident $($args:tt)*])*
479                $field_vis:vis $field_name:ident : $field_len:expr
480            ),+ $(,)?
481        }
482    ) => {
483        $(#[$outer])*
484        $visibility struct $name {
485            $(
486                $(#[$inner $($args)*])*
487                $field_vis $field_name: $base
488            ),*
489        }
490
491        impl $name {
492            #[allow(unused_assignments)]
493            fn from_raw(raw: $base) -> $name {
494                let mut raw_v = raw;
495                $(
496                    let mask: $base = (1 << $field_len) - 1;
497                    let $field_name = raw_v & mask;
498                    raw_v >>= $field_len;
499                )*
500                $name{$($field_name),*}
501            }
502            #[allow(unused_assignments)]
503            fn to_raw(&self) -> $base {
504                let mut raw: $base = 0;
505                let mut pos = 0;
506                $(
507                    raw |= self.$field_name << pos;
508                    pos += $field_len;
509                )*
510                raw
511            }
512        }
513
514        impl ByteStructLen for $name {
515            const BYTE_LEN: usize = <$base>::BYTE_LEN;
516        }
517
518        impl ByteStructUnspecifiedByteOrder for $name {
519            fn write_bytes_default_le(&self, bytes: &mut [u8]) {
520                self.to_raw().write_bytes_default_le(bytes);
521            }
522            fn read_bytes_default_le(bytes: &[u8]) -> Self {
523                <$name>::from_raw(<$base>::read_bytes_default_le(bytes))
524            }
525            fn write_bytes_default_be(&self, bytes: &mut [u8]) {
526                self.to_raw().write_bytes_default_be(bytes);
527            }
528            fn read_bytes_default_be(bytes: &[u8]) -> Self {
529                <$name>::from_raw(<$base>::read_bytes_default_be(bytes))
530            }
531        }
532    }
533}