bitfield/
lib.rs

1#![no_std]
2#![deny(
3    missing_docs,
4    unused_extern_crates,
5    unused_import_braces,
6    unused_qualifications
7)]
8//!  This crate provides macros to generate bitfield-like struct.
9//!
10//!  See the documentation of the macros for how to use them.
11//!
12//!  Examples and tests are also a great way to understand how to use these macros.
13
14/// Declares the fields of struct.
15///
16/// This macro will generate the methods to access the fields of a bitfield. It must be called
17/// from an `impl` block for a type that implements the `BitRange` and/or the `Bit` traits
18/// (which traits are required depending on what type of fields are used).
19///
20/// The syntax of this macro is composed of declarations ended by semicolons. There are two types
21/// of declarations: default type, and fields.
22///
23/// A default type is just a type followed by a semicolon. This will affect all the following field
24/// declarations.
25///
26/// A field declaration is composed of the following:
27///
28/// * Optional attributes (`#[...]`), documentation comments (`///`) are attributes;
29/// * An optional pub keyword to make the methods public
30/// * An optional type followed by a comma
31/// * Optionally, the word `into` followed by a type, followed by a comma
32/// * The getter and setter idents, separated by a comma
33/// * A colon
34/// * One to three expressions of type `usize`
35///
36/// The attributes and pub will be applied to the two methods generated.
37///
38/// If the `into` part is used, the getter will convert the field after reading it.
39///
40/// The getter and setter idents can be `_` to not generate one of the two. For example, if the
41/// setter is `_`, the field will be read-only.
42///
43/// The expressions at the end are the bit positions. Their meaning depends on the number of
44/// expressions:
45///
46///  * One expression: the field is a single bit. The type is ignored and `bool` is used. The trait
47///    `Bit` is used.
48///  * Two expressions: `msb, lsb`, the field is composed of the bits from `msb` to `lsb`, included.
49///  * Three expressions: `msb, lsb, count`, the field is an array. The first element is composed of
50///    the bits from `msb` to `lsb`. The following elements are consecutive bits range of the same
51///    size.
52///
53/// # Example
54///
55/// ```rust
56/// # #[macro_use] extern crate bitfield;
57/// # fn main() {}
58/// # struct FooBar(u64);
59/// # bitfield_bitrange!{struct FooBar(u64)}
60/// # impl From<u32> for FooBar{ fn from(_: u32) -> FooBar {unimplemented!()}}
61/// # impl From<FooBar> for u32{ fn from(_: FooBar) -> u32 {unimplemented!()}}
62/// # impl FooBar {
63/// bitfield_fields!{
64///     // The default type will be `u64
65///     u64;
66///     // filed1 is read-write, public, the methods are inline
67///     #[inline]
68///     pub field1, set_field1: 10, 0;
69///     // `field2` is  read-only, private, and of type bool.
70///     field2, _ : 0;
71///     // `field3` will be read as an `u32` and then converted to `FooBar`.
72///     // The setter is not affected, it still need an `u32` value.
73///     u32, into FooBar, field3, set_field3: 10, 0;
74///     // `field4` will be read as an `u32` and then converted to `FooBar`.
75///     // The setter will take a `FooBar`, and converted back to an `u32`.
76///     u32, from into FooBar, field4, set_field4: 10, 0;
77/// }
78/// # }
79/// ```
80#[macro_export(local_inner_macros)]
81macro_rules! bitfield_fields {
82    (only setter; @field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, _, $setter:ident: $msb:expr,
83     $lsb:expr, $count:expr) => {
84        $(#[$attribute])*
85        #[allow(unknown_lints)]
86        #[allow(eq_op)]
87        $($vis)* fn $setter(&mut self, index: usize, value: $from) {
88            use $crate::BitRangeMut;
89            __bitfield_debug_assert!(index < $count);
90            let width = $msb - $lsb + 1;
91            let lsb = $lsb + index*width;
92            let msb = lsb + width - 1;
93            self.set_bit_range(msb, lsb, $crate::Into::<$t>::into(value));
94        }
95    };
96    (only setter; @field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, _, $setter:ident: $msb:expr,
97     $lsb:expr) => {
98        $(#[$attribute])*
99        $($vis)* fn $setter(&mut self, value: $from) {
100            use $crate::BitRangeMut;
101            self.set_bit_range($msb, $lsb, $crate::Into::<$t>::into(value));
102        }
103    };
104    (only setter; @field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, _, $setter:ident: $bit:expr) => {
105        $(#[$attribute])*
106        $($vis)* fn $setter(&mut self, value: bool) {
107            use $crate::BitMut;
108            self.set_bit($bit, value);
109        }
110    };
111    (only getter; @field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, _, $setter:ident: $($exprs:expr),*) => {};
112
113    (only getter; @field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, $getter:ident, _: $msb:expr,
114     $lsb:expr, $count:expr) => {
115        $(#[$attribute])*
116        #[allow(unknown_lints)]
117        #[allow(eq_op)]
118        $($vis)* fn $getter(&self, index: usize) -> $into {
119            use $crate::BitRange;
120            __bitfield_debug_assert!(index < $count);
121            let width = $msb - $lsb + 1;
122            let lsb = $lsb + index*width;
123            let msb = lsb + width - 1;
124            let raw_value: $t = self.bit_range(msb, lsb);
125            $crate::Into::into(raw_value)
126        }
127    };
128    (only getter; @field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, $getter:ident, _: $msb:expr,
129     $lsb:expr) => {
130        $(#[$attribute])*
131        $($vis)* fn $getter(&self) -> $into {
132            use $crate::BitRange;
133            let raw_value: $t = self.bit_range($msb, $lsb);
134            $crate::Into::into(raw_value)
135        }
136    };
137    (only getter; @field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, $getter:ident, _: $bit:expr) => {
138        $(#[$attribute])*
139        $($vis)* fn $getter(&self) -> bool {
140            use $crate::Bit;
141            self.bit($bit)
142        }
143    };
144    (only setter; @field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, $getter:ident, _: $($exprs:expr),*) => {};
145
146    (only $only:tt; @field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, $getter:ident, $setter:ident:
147     $($exprs:expr),*) => {
148        bitfield_fields!(only $only; @field $(#[$attribute])* ($($vis)*) $t, $from, $into, $getter, _: $($exprs),*);
149        bitfield_fields!(only $only; @field $(#[$attribute])* ($($vis)*) $t, $from, $into, _, $setter: $($exprs),*);
150    };
151
152    (only $only:tt; $t:ty;) => {};
153    (only $only:tt; $default_ty:ty; pub $($rest:tt)*) => {
154        bitfield_fields!{only $only; $default_ty; () pub $($rest)*}
155    };
156    (only $only:tt; $default_ty:ty; #[$attribute:meta] $($rest:tt)*) => {
157        bitfield_fields!{only $only; $default_ty; (#[$attribute]) $($rest)*}
158    };
159    (only $only:tt; $default_ty:ty; ($(#[$attributes:meta])*) #[$attribute:meta] $($rest:tt)*) => {
160        bitfield_fields!{only $only; $default_ty; ($(#[$attributes])* #[$attribute]) $($rest)*}
161    };
162    (only $only:tt; $default_ty:ty; ($(#[$attribute:meta])*) pub $t:ty, from into $into:ty, $getter:tt, $setter:tt:
163     $($exprs:expr),*; $($rest:tt)*) => {
164        bitfield_fields!{only $only; @field $(#[$attribute])* (pub) $t, $into, $into, $getter, $setter: $($exprs),*}
165        bitfield_fields!{only $only; $default_ty; $($rest)*}
166    };
167    (only $only:tt; $default_ty:ty; ($(#[$attribute:meta])*) pub $t:ty, into $into:ty, $getter:tt, $setter:tt:
168     $($exprs:expr),*; $($rest:tt)*) => {
169        bitfield_fields!{only $only; @field $(#[$attribute])* (pub) $t, $t, $into, $getter, $setter: $($exprs),*}
170        bitfield_fields!{only $only; $default_ty; $($rest)*}
171    };
172    (only $only:tt; $default_ty:ty; ($(#[$attribute:meta])*) pub $t:ty, $getter:tt, $setter:tt:  $($exprs:expr),*;
173     $($rest:tt)*) => {
174        bitfield_fields!{only $only; @field $(#[$attribute])* (pub) $t, $t, $t, $getter, $setter: $($exprs),*}
175        bitfield_fields!{only $only; $default_ty; $($rest)*}
176    };
177    (only $only:tt; $default_ty:ty; ($(#[$attribute:meta])*) pub from into $into:ty, $getter:tt, $setter:tt:
178     $($exprs:expr),*; $($rest:tt)*) => {
179        bitfield_fields!{only $only; @field $(#[$attribute])* (pub) $default_ty, $into, $into, $getter, $setter:
180                         $($exprs),*}
181        bitfield_fields!{only $only; $default_ty; $($rest)*}
182    };
183    (only $only:tt; $default_ty:ty; ($(#[$attribute:meta])*) pub into $into:ty, $getter:tt, $setter:tt:
184     $($exprs:expr),*; $($rest:tt)*) => {
185        bitfield_fields!{only $only; @field $(#[$attribute])* (pub) $default_ty, $default_ty, $into, $getter, $setter:
186                         $($exprs),*}
187        bitfield_fields!{only $only; $default_ty; $($rest)*}
188    };
189    (only $only:tt; $default_ty:ty; ($(#[$attribute:meta])*) pub $getter:tt, $setter:tt:  $($exprs:expr),*;
190     $($rest:tt)*) => {
191        bitfield_fields!{only $only; @field $(#[$attribute])* (pub) $default_ty, $default_ty, $default_ty, $getter, $setter:
192                                $($exprs),*}
193        bitfield_fields!{only $only; $default_ty; $($rest)*}
194    };
195
196    (only $only:tt; $default_ty:ty; ($(#[$attribute:meta])*) $t:ty, from into $into:ty, $getter:tt, $setter:tt:
197     $($exprs:expr),*; $($rest:tt)*) => {
198        bitfield_fields!{only $only; @field $(#[$attribute])* () $t, $into, $into, $getter, $setter: $($exprs),*}
199        bitfield_fields!{only $only; $default_ty; $($rest)*}
200    };
201
202    (only $only:tt; $default_ty:ty; ($(#[$attribute:meta])*) $t:ty, into $into:ty, $getter:tt, $setter:tt:
203     $($exprs:expr),*; $($rest:tt)*) => {
204        bitfield_fields!{only $only; @field $(#[$attribute])* () $t, $t, $into, $getter, $setter: $($exprs),*}
205        bitfield_fields!{only $only; $default_ty; $($rest)*}
206    };
207
208    (only $only:tt; $default_ty:ty; ($(#[$attribute:meta])*) $t:ty, $getter:tt, $setter:tt:  $($exprs:expr),*;
209     $($rest:tt)*) => {
210        bitfield_fields!{only $only; @field $(#[$attribute])* () $t, $t, $t, $getter, $setter: $($exprs),*}
211        bitfield_fields!{only $only; $default_ty; $($rest)*}
212    };
213    (only $only:tt; $default_ty:ty; ($(#[$attribute:meta])*) from into $into:ty, $getter:tt, $setter:tt:
214     $($exprs:expr),*; $($rest:tt)*) => {
215        bitfield_fields!{only $only; @field $(#[$attribute])* () $default_ty, $into, $into, $getter, $setter:
216                         $($exprs),*}
217        bitfield_fields!{only $only; $default_ty; $($rest)*}
218    };
219    (only $only:tt; $default_ty:ty; ($(#[$attribute:meta])*) into $into:ty, $getter:tt, $setter:tt:
220     $($exprs:expr),*; $($rest:tt)*) => {
221        bitfield_fields!{only $only; @field $(#[$attribute])* () $default_ty, $default_ty, $into, $getter, $setter:
222                         $($exprs),*}
223        bitfield_fields!{only $only; $default_ty; $($rest)*}
224    };
225    (only $only:tt; $default_ty:ty; ($(#[$attribute:meta])*) $getter:tt, $setter:tt:  $($exprs:expr),*;
226     $($rest:tt)*) => {
227        bitfield_fields!{only $only; @field $(#[$attribute])* () $default_ty, $default_ty, $default_ty, $getter, $setter:
228                                $($exprs),*}
229        bitfield_fields!{only $only; $default_ty; $($rest)*}
230    };
231    (only $only:tt; $previous_default_ty:ty; $default_ty:ty; $($rest:tt)*) => {
232        bitfield_fields!{only $only; $default_ty; $($rest)*}
233    };
234    (only $only:tt; $default_ty:ty; $($rest:tt)*) => {
235        bitfield_fields!{only $only; $default_ty; () $($rest)*}
236    };
237    (only $only:tt; $($rest:tt)*) => {
238        bitfield_fields!{only $only; SET_A_DEFAULT_TYPE_OR_SPECIFY_THE_TYPE_FOR_EACH_FIELDS; $($rest)*}
239    };
240    ($($rest:tt)*) => {
241        bitfield_fields!{only getter; $($rest)*}
242        bitfield_fields!{only setter; $($rest)*}
243    }
244}
245
246/// Generates a `fmt::Debug` implementation.
247///
248/// This macros must be called from a `impl Debug for ...` block. It will generate the `fmt` method.
249///
250/// In most of the case, you will not directly call this macros, but use `bitfield`.
251///
252/// The syntax is `struct TheNameOfTheStruct` followed by the syntax of `bitfield_fields`.
253///
254/// The write-only fields are ignored.
255///
256/// # Example
257///
258/// ```rust
259/// # #[macro_use] extern crate bitfield;
260/// struct FooBar(u32);
261/// bitfield_bitrange!{struct FooBar(u32)}
262/// impl FooBar{
263///     bitfield_fields!{
264///        u32;
265///        field1, _: 7, 0;
266///        field2, _: 31, 24;
267///     }
268/// }
269///
270/// impl std::fmt::Debug for FooBar {
271///     bitfield_debug!{
272///        struct FooBar;
273///        field1, _: 7, 0;
274///        field2, _: 31, 24;
275///     }
276/// }
277///
278/// fn main() {
279///     let foobar = FooBar(0x11223344);
280///     println!("{:?}", foobar);
281
282/// }
283/// ```
284#[macro_export(local_inner_macros)]
285macro_rules! bitfield_debug {
286    (struct $name:ident; $($rest:tt)*) => {
287        fn fmt(&self, f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result {
288            let mut debug_struct = f.debug_struct(__bitfield_stringify!($name));
289            debug_struct.field(".0", &self.0);
290            bitfield_debug!{debug_struct, self, $($rest)*}
291            debug_struct.finish()
292        }
293    };
294    ($debug_struct:ident, $self:ident, #[$attribute:meta] $($rest:tt)*) => {
295        bitfield_debug!{$debug_struct, $self, $($rest)*}
296    };
297    ($debug_struct:ident, $self:ident, pub $($rest:tt)*) => {
298        bitfield_debug!{$debug_struct, $self, $($rest)*}
299    };
300    ($debug_struct:ident, $self:ident, _, $setter:tt: $($exprs:expr),*; $($rest:tt)*) => {
301        bitfield_debug!{$debug_struct, $self, $($rest)*}
302    };
303    ($debug_struct:ident, $self:ident, $type:ty; $($rest:tt)*) => {
304        bitfield_debug!{$debug_struct, $self, $($rest)*}
305    };
306    ($debug_struct:ident, $self:ident, $getter:ident, $setter:tt: $msb:expr, $lsb:expr, $count:expr;
307     $($rest:tt)*) => {
308        let mut array = [$self.$getter(0); $count];
309        for (i, e) in (&mut array).into_iter().enumerate() {
310            *e = $self.$getter(i);
311        }
312        $debug_struct.field(__bitfield_stringify!($getter), &array);
313        bitfield_debug!{$debug_struct, $self, $($rest)*}
314    };
315    ($debug_struct:ident, $self:ident, $getter:ident, $setter:tt: $($exprs:expr),*; $($rest:tt)*)
316        => {
317        $debug_struct.field(__bitfield_stringify!($getter), &$self.$getter());
318        bitfield_debug!{$debug_struct, $self, $($rest)*}
319    };
320    ($debug_struct:ident, $self:ident, from into $into:ty, $($rest:tt)*) => {
321        bitfield_debug!{$debug_struct, $self, $($rest)*}
322    };
323    ($debug_struct:ident, $self:ident, into $into:ty, $($rest:tt)*) => {
324        bitfield_debug!{$debug_struct, $self, $($rest)*}
325    };
326    ($debug_struct:ident, $self:ident, $type:ty, $($rest:tt)*) => {
327        bitfield_debug!{$debug_struct, $self, $($rest)*}
328    };
329    ($debug_struct:ident, $self:ident, ) => {};
330}
331
332/// Implements `BitRange` and `BitRangeMut` for a tuple struct (or "newtype").
333///
334/// This macro will generate an implementation of the `BitRange` trait for an existing single
335/// element tuple struct.
336///
337/// The syntax is more or less the same as declaring a "newtype", **without** the attributes,
338/// documentation comments and pub keyword.
339///
340/// The difference with a normal "newtype" is the type in parentheses. If the type is `[t]` (where
341/// `t` is any of the unsigned integer type), the "newtype" will be generic and implement
342/// `BitRange` for `T: AsRef<[t]>` and `BitRangeMut` for `T: AsMut<[t]>` (for example a slice, an array or a `Vec`). You can
343/// also use `MSB0 [t]`. The difference will be the positions of the bit. You can use the
344/// `bits_positions` example to see where each bits is. If the type is neither of this two, the
345/// "newtype" will wrap a value of the specified type and implements `BitRange` the same ways as
346/// the wrapped type.
347///
348/// # Examples
349///
350/// ```rust
351/// # #[macro_use] extern crate bitfield;
352/// # fn main() {}
353/// struct BitField1(u32);
354/// bitfield_bitrange!{struct BitField1(u32)}
355///
356/// struct BitField2<T>(T);
357/// bitfield_bitrange!{struct BitField2([u8])}
358///
359/// struct BitField3<T>(T);
360/// bitfield_bitrange!{struct BitField3(MSB0 [u8])}
361/// ```
362///
363#[macro_export(local_inner_macros)]
364macro_rules! bitfield_bitrange {
365    (@impl_bitrange_slice $name:ident, $slice_ty:ty, $bitrange_ty:ty) => {
366        impl<T: AsRef<[$slice_ty]>> $crate::BitRange<$bitrange_ty>
367            for $name<T> {
368                fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
369                    let bit_len = $crate::size_of::<$slice_ty>()*8;
370                    let value_bit_len = $crate::size_of::<$bitrange_ty>()*8;
371                    let mut value = 0;
372                    for i in (lsb..=msb).rev() {
373                        value <<= 1;
374                        value |= ((self.0.as_ref()[i/bit_len] >> (i%bit_len)) & 1) as $bitrange_ty;
375                    }
376                    value << (value_bit_len - (msb - lsb + 1)) >> (value_bit_len - (msb - lsb + 1))
377                }
378        }
379        impl<T: AsMut<[$slice_ty]>> $crate::BitRangeMut<$bitrange_ty>
380            for $name<T> {
381
382                fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
383                    let bit_len = $crate::size_of::<$slice_ty>()*8;
384                    let mut value = value;
385                    for i in lsb..=msb {
386                        self.0.as_mut()[i/bit_len] &= !(1 << (i%bit_len));
387                        self.0.as_mut()[i/bit_len] |= (value & 1) as $slice_ty << (i%bit_len);
388                        value >>= 1;
389                    }
390                }
391            }
392    };
393    (@impl_bitrange_slice_msb0 $name:ident, $slice_ty:ty, $bitrange_ty:ty) => {
394        impl<T: AsRef<[$slice_ty]>> $crate::BitRange<$bitrange_ty>
395            for $name<T> {
396            fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
397                let bit_len = $crate::size_of::<$slice_ty>()*8;
398                let value_bit_len = $crate::size_of::<$bitrange_ty>()*8;
399                let mut value = 0;
400                for i in lsb..=msb {
401                    value <<= 1;
402                    value |= ((self.0.as_ref()[i/bit_len] >> (bit_len - i%bit_len - 1)) & 1)
403                        as $bitrange_ty;
404                }
405                value << (value_bit_len - (msb - lsb + 1)) >> (value_bit_len - (msb - lsb + 1))
406            }
407        }
408        impl<T: AsMut<[$slice_ty]>> $crate::BitRangeMut<$bitrange_ty>
409            for $name<T> {
410            fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
411                let bit_len = $crate::size_of::<$slice_ty>()*8;
412                let mut value = value;
413                for i in (lsb..=msb).rev() {
414                    self.0.as_mut()[i/bit_len] &= !(1 << (bit_len - i%bit_len - 1));
415                    self.0.as_mut()[i/bit_len] |= (value & 1) as $slice_ty
416                        << (bit_len - i%bit_len - 1);
417                    value >>= 1;
418                }
419            }
420        }
421    };
422    (struct $name:ident([$t:ty])) => {
423        bitfield_bitrange!(@impl_bitrange_slice $name, $t, u8);
424        bitfield_bitrange!(@impl_bitrange_slice $name, $t, u16);
425        bitfield_bitrange!(@impl_bitrange_slice $name, $t, u32);
426        bitfield_bitrange!(@impl_bitrange_slice $name, $t, u64);
427        bitfield_bitrange!(@impl_bitrange_slice $name, $t, u128);
428        bitfield_bitrange!(@impl_bitrange_slice $name, $t, i8);
429        bitfield_bitrange!(@impl_bitrange_slice $name, $t, i16);
430        bitfield_bitrange!(@impl_bitrange_slice $name, $t, i32);
431        bitfield_bitrange!(@impl_bitrange_slice $name, $t, i64);
432        bitfield_bitrange!(@impl_bitrange_slice $name, $t, i128);
433    };
434    (struct $name:ident(MSB0 [$t:ty])) => {
435        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u8);
436        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u16);
437        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u32);
438        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u64);
439        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u128);
440        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i8);
441        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i16);
442        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i32);
443        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i64);
444        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i128);
445    };
446    (struct $name:ident($t:ty)) => {
447        impl<T> $crate::BitRange<T> for $name where $t: $crate::BitRange<T> {
448            fn bit_range(&self, msb: usize, lsb: usize) -> T {
449                self.0.bit_range(msb, lsb)
450            }
451        }
452        impl<T> $crate::BitRangeMut<T> for $name where $t: $crate::BitRangeMut<T> {
453            fn set_bit_range(&mut self, msb: usize, lsb: usize, value: T) {
454                self.0.set_bit_range(msb, lsb, value);
455            }
456        }
457    };
458}
459
460/// Combines `bitfield_bitrange` and `bitfield_fields`.
461///
462/// The syntax of this macro is the syntax of a tuple struct, including attributes and
463/// documentation comments, followed by a semicolon, some optional elements, and finally the fields
464/// as described in the `bitfield_fields` documentation.
465///
466/// The first optional element is `no default BitRange;`. With that, no implementation of
467/// `BitRange` will be generated.
468///
469/// The second optional element is `impl Debug;`. This will generate an implementation of
470/// `fmt::Debug` with the `bitfield_debug` macro.
471///
472/// The difference with calling those macros separately is that `bitfield_fields` is called
473/// from an appropriate `impl` block. If you use the non-slice form of `bitfield_bitrange`, the
474/// default type for `bitfield_fields` will be set to the wrapped fields.
475///
476/// See the documentation of these macros for more information on their respective syntax.
477///
478/// # Example
479///
480/// ```rust
481/// # #[macro_use] extern crate bitfield;
482/// # fn main() {}
483/// bitfield!{
484///   pub struct BitField1(u16);
485///   impl Debug;
486///   // The fields default to u16
487///   field1, set_field1: 10, 0;
488///   pub field2, _ : 12, 3;
489/// }
490/// ```
491///
492/// or with a custom `BitRange` and `BitRangeMut` implementation :
493/// ```rust
494/// # #[macro_use] extern crate bitfield;
495/// # use bitfield::{BitRange, BitRangeMut};
496/// # fn main() {}
497/// bitfield!{
498///   pub struct BitField1(u16);
499///   no default BitRange;
500///   impl Debug;
501///   u8;
502///   field1, set_field1: 10, 0;
503///   pub field2, _ : 12, 3;
504/// }
505/// impl BitRange<u8> for BitField1 {
506///     fn bit_range(&self, msb: usize, lsb: usize) -> u8 {
507///         let width = msb - lsb + 1;
508///         let mask = (1 << width) - 1;
509///         ((self.0 >> lsb) & mask) as u8
510///     }
511/// }
512/// impl BitRangeMut<u8> for BitField1 {
513///     fn set_bit_range(&mut self, msb: usize, lsb: usize, value: u8) {
514///         self.0 = (value as u16) << lsb;
515///     }
516/// }
517/// ```
518#[macro_export(local_inner_macros)]
519macro_rules! bitfield {
520    ($(#[$attribute:meta])* pub struct $($rest:tt)*) => {
521        bitfield!($(#[$attribute])* (pub) struct $($rest)*);
522    };
523    ($(#[$attribute:meta])* struct $($rest:tt)*) => {
524        bitfield!($(#[$attribute])* () struct $($rest)*);
525    };
526    // Force `impl Debug` to always be after `no default BitRange` it the two are present.
527    // This simplify the rest of the macro.
528    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($($type:tt)*); impl Debug; no default BitRange; $($rest:tt)*) => {
529         bitfield!{$(#[$attribute])* ($($vis)*) struct $name($($type)*); no default BitRange; impl Debug; $($rest)*}
530     };
531
532    // If we have `impl Debug` without `no default BitRange`, we will still match, because when
533    // we call `bitfield_bitrange`, we add `no default BitRange`.
534    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty]); no default BitRange; impl Debug; $($rest:tt)*) => {
535        impl<T: AsRef<[$t]> + $crate::fmt::Debug> $crate::fmt::Debug for $name<T> {
536            bitfield_debug!{struct $name; $($rest)*}
537        }
538
539        bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange;  $($rest)*}
540    };
541    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty]); no default BitRange; $($rest:tt)*) => {
542        $(#[$attribute])*
543        $($vis)* struct $name<T>(pub T);
544
545        //impl<T: AsMut<[$t]> + AsRef<[$t]>> $name<T> {
546        //    bitfield_fields!{$($rest)*}
547        //}
548        impl<T: AsRef<[$t]>> $name<T> {
549           bitfield_fields!{only getter; $($rest)*}
550        }
551        impl<T: AsMut<[$t]>> $name<T> {
552           bitfield_fields!{only setter; $($rest)*}
553        }
554    };
555    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty]); $($rest:tt)*) => {
556        bitfield_bitrange!(struct $name([$t]));
557        bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange; $($rest)*}
558    };
559
560    // The only difference between the MSB0 version anf the non-MSB0 version, is the BitRange
561    // implementation. We delegate everything else to the non-MSB0 version of the macro.
562    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident(MSB0 [$t:ty]); no default BitRange; $($rest:tt)*) => {
563        bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange; $($rest)*}
564    };
565    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident(MSB0 [$t:ty]); $($rest:tt)*) => {
566        bitfield_bitrange!(struct $name(MSB0 [$t]));
567        bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange; $($rest)*}
568    };
569
570    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); no default BitRange; impl Debug; $($rest:tt)*) => {
571        impl $crate::fmt::Debug for $name {
572            bitfield_debug!{struct $name; $($rest)*}
573        }
574
575        bitfield!{$(#[$attribute])* ($($vis)*) struct $name($t); no default BitRange; $($rest)*}
576    };
577    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); no default BitRange; $($rest:tt)*) => {
578        $(#[$attribute])*
579        $($vis)* struct $name(pub $t);
580
581        impl $name {
582            bitfield_fields!{$t; $($rest)*}
583         }
584    };
585    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); $($rest:tt)*) => {
586        bitfield_bitrange!(struct $name($t));
587        bitfield!{$(#[$attribute])* ($($vis)*) struct $name($t); no default BitRange; $($rest)*}
588    };
589}
590
591#[doc(hidden)]
592pub use core::convert::Into;
593#[doc(hidden)]
594pub use core::fmt;
595#[doc(hidden)]
596pub use core::mem::size_of;
597
598/// A trait to get ranges of bits.
599pub trait BitRange<T> {
600    /// Get a range of bits.
601    fn bit_range(&self, msb: usize, lsb: usize) -> T;
602}
603
604/// A trait to set ranges of bits.
605pub trait BitRangeMut<T> {
606    /// Set a range of bits.
607    fn set_bit_range(&mut self, msb: usize, lsb: usize, value: T);
608}
609
610/// A trait to get a single bit.
611///
612/// This trait is implemented for all type that implement `BitRange<u8>`.
613pub trait Bit {
614    /// Get a single bit.
615    fn bit(&self, bit: usize) -> bool;
616}
617
618/// A trait to set a single bit.
619///
620/// This trait is implemented for all type that implement `BitRangeMut<u8>`.
621pub trait BitMut {
622    /// Set a single bit.
623    fn set_bit(&mut self, bit: usize, value: bool);
624}
625
626impl<T: BitRange<u8>> Bit for T {
627    fn bit(&self, bit: usize) -> bool {
628        self.bit_range(bit, bit) != 0
629    }
630}
631
632impl<T: BitRangeMut<u8>> BitMut for T {
633    fn set_bit(&mut self, bit: usize, value: bool) {
634        self.set_bit_range(bit, bit, value as u8);
635    }
636}
637
638macro_rules! impl_bitrange_for_u {
639    ($t:ty, $bitrange_ty:ty) => {
640        impl BitRange<$bitrange_ty> for $t {
641            #[inline]
642            #[allow(clippy::cast_lossless)]
643            fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
644                let bit_len = size_of::<$t>()*8;
645                let result_bit_len = size_of::<$bitrange_ty>()*8;
646                let result = ((*self << (bit_len - msb - 1)) >> (bit_len - msb - 1 + lsb))
647                    as $bitrange_ty;
648                result << (result_bit_len - (msb - lsb + 1)) >> (result_bit_len - (msb - lsb + 1))
649            }
650        }
651
652        impl BitRangeMut<$bitrange_ty> for $t {
653            #[inline]
654            #[allow(clippy::cast_lossless)]
655            fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
656                let bit_len = size_of::<$t>()*8;
657                let mask: $t = !(0 as $t)
658                    << (bit_len - msb - 1)
659                    >> (bit_len - msb - 1 + lsb)
660                    << (lsb);
661                *self &= !mask;
662                *self |= (value as $t << lsb) & mask;
663            }
664        }
665    }
666}
667
668macro_rules! impl_bitrange_for_u_combinations {
669((),($($bitrange_ty:ty),*)) => {
670
671};
672(($t:ty),($($bitrange_ty:ty),*)) => {
673        $(impl_bitrange_for_u!{$t, $bitrange_ty})*
674};
675    (($t_head:ty, $($t_rest:ty),*),($($bitrange_ty:ty),*)) => {
676        impl_bitrange_for_u_combinations!{($t_head), ($($bitrange_ty),*)}
677        impl_bitrange_for_u_combinations!{($($t_rest),*), ($($bitrange_ty),*)}
678    };
679}
680
681impl_bitrange_for_u_combinations! {(u8, u16, u32, u64, u128), (u8, u16, u32, u64, u128)}
682impl_bitrange_for_u_combinations! {(u8, u16, u32, u64, u128), (i8, i16, i32, i64, i128)}
683
684// Same as std::stringify but callable from local_inner_macros macros defined inside
685// this crate.
686#[macro_export]
687#[doc(hidden)]
688macro_rules! __bitfield_stringify {
689    ($s:ident) => {
690        stringify!($s)
691    };
692}
693
694// Same as std::debug_assert but callable from local_inner_macros macros defined inside
695// this crate.
696#[macro_export]
697#[doc(hidden)]
698macro_rules! __bitfield_debug_assert {
699    ($e:expr) => {
700        debug_assert!($e)
701    };
702}