1#![no_std]
2#![deny(
3    missing_docs,
4    unused_extern_crates,
5    unused_import_braces,
6    unused_qualifications
7)]
8
9#[macro_export(local_inner_macros)]
82macro_rules! bitfield_fields {
83    (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, _, $setter:ident: $msb:expr,
84     $lsb:expr, $count:expr) => {
85        $(#[$attribute])*
86        #[allow(unknown_lints)]
87        #[allow(eq_op)]
88        $($vis)* fn $setter(&mut self, index: usize, value: $from) {
89            use $crate::BitRange;
90            __bitfield_debug_assert!(index < $count);
91            let width = $msb - $lsb + 1;
92            let lsb = $lsb + index*width;
93            let msb = lsb + width - 1;
94            self.set_bit_range(msb, lsb, $crate::Into::<$t>::into(value));
95        }
96    };
97    (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, _, $setter:ident: $msb:expr,
98     $lsb:expr) => {
99        $(#[$attribute])*
100        $($vis)* fn $setter(&mut self, value: $from) {
101            use $crate::BitRange;
102            self.set_bit_range($msb, $lsb, $crate::Into::<$t>::into(value));
103        }
104    };
105    (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, _, $setter:ident: $bit:expr) => {
106        $(#[$attribute])*
107        $($vis)* fn $setter(&mut self, value: bool) {
108            use $crate::Bit;
109            self.set_bit($bit, value);
110        }
111    };
112    (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, $getter:ident, _: $msb:expr,
113     $lsb:expr, $count:expr) => {
114        $(#[$attribute])*
115        #[allow(unknown_lints)]
116        #[allow(eq_op)]
117        $($vis)* fn $getter(&self, index: usize) -> $into {
118            use $crate::BitRange;
119            __bitfield_debug_assert!(index < $count);
120            let width = $msb - $lsb + 1;
121            let lsb = $lsb + index*width;
122            let msb = lsb + width - 1;
123            let raw_value: $t = self.bit_range(msb, lsb);
124            $crate::Into::into(raw_value)
125        }
126    };
127    (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, $getter:ident, _: $msb:expr,
128     $lsb:expr) => {
129        $(#[$attribute])*
130        $($vis)* fn $getter(&self) -> $into {
131            use $crate::BitRange;
132            let raw_value: $t = self.bit_range($msb, $lsb);
133            $crate::Into::into(raw_value)
134        }
135    };
136    (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, $getter:ident, _: $bit:expr) => {
137        $(#[$attribute])*
138        $($vis)* fn $getter(&self) -> bool {
139            use $crate::Bit;
140            self.bit($bit)
141        }
142    };
143    (@field $(#[$attribute:meta])* ($($vis:tt)*) $t:ty, $from:ty, $into:ty, $getter:ident, $setter:ident:
144     $($exprs:expr),*) => {
145        bitfield_fields!(@field $(#[$attribute])* ($($vis)*) $t, $from, $into, $getter, _: $($exprs),*);
146        bitfield_fields!(@field $(#[$attribute])* ($($vis)*) $t, $from, $into, _, $setter: $($exprs),*);
147    };
148
149    ($t:ty;) => {};
150    ($default_ty:ty; pub $($rest:tt)*) => {
151        bitfield_fields!{$default_ty; () pub $($rest)*}
152    };
153    ($default_ty:ty; #[$attribute:meta] $($rest:tt)*) => {
154        bitfield_fields!{$default_ty; (#[$attribute]) $($rest)*}
155    };
156    ($default_ty:ty; ($(#[$attributes:meta])*) #[$attribute:meta] $($rest:tt)*) => {
157        bitfield_fields!{$default_ty; ($(#[$attributes])* #[$attribute]) $($rest)*}
158    };
159    ($default_ty:ty; ($(#[$attribute:meta])*) pub $t:ty, from into $into:ty, $getter:tt, $setter:tt:
160     $($exprs:expr),*; $($rest:tt)*) => {
161        bitfield_fields!{@field $(#[$attribute])* (pub) $t, $into, $into, $getter, $setter: $($exprs),*}
162        bitfield_fields!{$default_ty; $($rest)*}
163    };
164    ($default_ty:ty; ($(#[$attribute:meta])*) pub $t:ty, into $into:ty, $getter:tt, $setter:tt:
165     $($exprs:expr),*; $($rest:tt)*) => {
166        bitfield_fields!{@field $(#[$attribute])* (pub) $t, $t, $into, $getter, $setter: $($exprs),*}
167        bitfield_fields!{$default_ty; $($rest)*}
168    };
169    ($default_ty:ty; ($(#[$attribute:meta])*) pub $t:ty, $getter:tt, $setter:tt:  $($exprs:expr),*;
170     $($rest:tt)*) => {
171        bitfield_fields!{@field $(#[$attribute])* (pub) $t, $t, $t, $getter, $setter: $($exprs),*}
172        bitfield_fields!{$default_ty; $($rest)*}
173    };
174    ($default_ty:ty; ($(#[$attribute:meta])*) pub from into $into:ty, $getter:tt, $setter:tt:
175     $($exprs:expr),*; $($rest:tt)*) => {
176        bitfield_fields!{@field $(#[$attribute])* (pub) $default_ty, $into, $into, $getter, $setter:
177                         $($exprs),*}
178        bitfield_fields!{$default_ty; $($rest)*}
179    };
180    ($default_ty:ty; ($(#[$attribute:meta])*) pub into $into:ty, $getter:tt, $setter:tt:
181     $($exprs:expr),*; $($rest:tt)*) => {
182        bitfield_fields!{@field $(#[$attribute])* (pub) $default_ty, $default_ty, $into, $getter, $setter:
183                         $($exprs),*}
184        bitfield_fields!{$default_ty; $($rest)*}
185    };
186    ($default_ty:ty; ($(#[$attribute:meta])*) pub $getter:tt, $setter:tt:  $($exprs:expr),*;
187     $($rest:tt)*) => {
188        bitfield_fields!{@field $(#[$attribute])* (pub) $default_ty, $default_ty, $default_ty, $getter, $setter:
189                                $($exprs),*}
190        bitfield_fields!{$default_ty; $($rest)*}
191    };
192
193    ($default_ty:ty; ($(#[$attribute:meta])*) $t:ty, from into $into:ty, $getter:tt, $setter:tt:
194     $($exprs:expr),*; $($rest:tt)*) => {
195        bitfield_fields!{@field $(#[$attribute])* () $t, $into, $into, $getter, $setter: $($exprs),*}
196        bitfield_fields!{$default_ty; $($rest)*}
197    };
198
199    ($default_ty:ty; ($(#[$attribute:meta])*) $t:ty, into $into:ty, $getter:tt, $setter:tt:
200     $($exprs:expr),*; $($rest:tt)*) => {
201        bitfield_fields!{@field $(#[$attribute])* () $t, $t, $into, $getter, $setter: $($exprs),*}
202        bitfield_fields!{$default_ty; $($rest)*}
203    };
204
205    ($default_ty:ty; ($(#[$attribute:meta])*) $t:ty, $getter:tt, $setter:tt:  $($exprs:expr),*;
206     $($rest:tt)*) => {
207        bitfield_fields!{@field $(#[$attribute])* () $t, $t, $t, $getter, $setter: $($exprs),*}
208        bitfield_fields!{$default_ty; $($rest)*}
209    };
210    ($default_ty:ty; ($(#[$attribute:meta])*) from into $into:ty, $getter:tt, $setter:tt:
211     $($exprs:expr),*; $($rest:tt)*) => {
212        bitfield_fields!{@field $(#[$attribute])* () $default_ty, $into, $into, $getter, $setter:
213                         $($exprs),*}
214        bitfield_fields!{$default_ty; $($rest)*}
215    };
216    ($default_ty:ty; ($(#[$attribute:meta])*) into $into:ty, $getter:tt, $setter:tt:
217     $($exprs:expr),*; $($rest:tt)*) => {
218        bitfield_fields!{@field $(#[$attribute])* () $default_ty, $default_ty, $into, $getter, $setter:
219                         $($exprs),*}
220        bitfield_fields!{$default_ty; $($rest)*}
221    };
222    ($default_ty:ty; ($(#[$attribute:meta])*) $getter:tt, $setter:tt:  $($exprs:expr),*;
223     $($rest:tt)*) => {
224        bitfield_fields!{@field $(#[$attribute])* () $default_ty, $default_ty, $default_ty, $getter, $setter:
225                                $($exprs),*}
226        bitfield_fields!{$default_ty; $($rest)*}
227    };
228    ($previous_default_ty:ty; $default_ty:ty; $($rest:tt)*) => {
229        bitfield_fields!{$default_ty; $($rest)*}
230    };
231    ($default_ty:ty; $($rest:tt)*) => {
232        bitfield_fields!{$default_ty; () $($rest)*}
233    };
234    ($($rest:tt)*) => {
235        bitfield_fields!{SET_A_DEFAULT_TYPE_OR_SPECIFY_THE_TYPE_FOR_EACH_FIELDS; $($rest)*}
236    }
237}
238
239#[macro_export(local_inner_macros)]
278macro_rules! bitfield_debug {
279    (struct $name:ident; $($rest:tt)*) => {
280        fn fmt(&self, f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result {
281            let mut debug_struct = f.debug_struct(__bitfield_stringify!($name));
282            debug_struct.field(".0", &self.0);
283            bitfield_debug!{debug_struct, self, $($rest)*}
284            debug_struct.finish()
285        }
286    };
287    ($debug_struct:ident, $self:ident, #[$attribute:meta] $($rest:tt)*) => {
288        bitfield_debug!{$debug_struct, $self, $($rest)*}
289    };
290    ($debug_struct:ident, $self:ident, pub $($rest:tt)*) => {
291        bitfield_debug!{$debug_struct, $self, $($rest)*}
292    };
293    ($debug_struct:ident, $self:ident, _, $setter:tt: $($exprs:expr),*; $($rest:tt)*) => {
294        bitfield_debug!{$debug_struct, $self, $($rest)*}
295    };
296    ($debug_struct:ident, $self:ident, $type:ty; $($rest:tt)*) => {
297        bitfield_debug!{$debug_struct, $self, $($rest)*}
298    };
299    ($debug_struct:ident, $self:ident, $getter:ident, $setter:tt: $msb:expr, $lsb:expr, $count:expr;
300     $($rest:tt)*) => {
301        let mut array = [$self.$getter(0); $count];
302        for (i, e) in (&mut array).into_iter().enumerate() {
303            *e = $self.$getter(i);
304        }
305        $debug_struct.field(__bitfield_stringify!($getter), &array);
306        bitfield_debug!{$debug_struct, $self, $($rest)*}
307    };
308    ($debug_struct:ident, $self:ident, $getter:ident, $setter:tt: $($exprs:expr),*; $($rest:tt)*)
309        => {
310        $debug_struct.field(__bitfield_stringify!($getter), &$self.$getter());
311        bitfield_debug!{$debug_struct, $self, $($rest)*}
312    };
313    ($debug_struct:ident, $self:ident, from into $into:ty, $($rest:tt)*) => {
314        bitfield_debug!{$debug_struct, $self, $($rest)*}
315    };
316    ($debug_struct:ident, $self:ident, into $into:ty, $($rest:tt)*) => {
317        bitfield_debug!{$debug_struct, $self, $($rest)*}
318    };
319    ($debug_struct:ident, $self:ident, $type:ty, $($rest:tt)*) => {
320        bitfield_debug!{$debug_struct, $self, $($rest)*}
321    };
322    ($debug_struct:ident, $self:ident, ) => {};
323}
324
325#[macro_export(local_inner_macros)]
357macro_rules! bitfield_bitrange {
358    (@impl_bitrange_slice $name:ident, $slice_ty:ty, $bitrange_ty:ty) => {
359        impl<T: AsMut<[$slice_ty]> + AsRef<[$slice_ty]>> $crate::BitRange<$bitrange_ty>
360            for $name<T> {
361                fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
362                    let bit_len = $crate::size_of::<$slice_ty>()*8;
363                    let value_bit_len = $crate::size_of::<$bitrange_ty>()*8;
364                    let mut value = 0;
365                    for i in (lsb..=msb).rev() {
366                        value <<= 1;
367                        value |= ((self.0.as_ref()[i/bit_len] >> (i%bit_len)) & 1) as $bitrange_ty;
368                    }
369                    value << (value_bit_len - (msb - lsb + 1)) >> (value_bit_len - (msb - lsb + 1))
370                }
371
372                fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
373                    let bit_len = $crate::size_of::<$slice_ty>()*8;
374                    let mut value = value;
375                    for i in lsb..=msb {
376                        self.0.as_mut()[i/bit_len] &= !(1 << (i%bit_len));
377                        self.0.as_mut()[i/bit_len] |= (value & 1) as $slice_ty << (i%bit_len);
378                        value >>= 1;
379                    }
380                }
381            }
382    };
383    (@impl_bitrange_slice_msb0 $name:ident, $slice_ty:ty, $bitrange_ty:ty) => {
384        impl<T: AsMut<[$slice_ty]> + AsRef<[$slice_ty]>> $crate::BitRange<$bitrange_ty>
385            for $name<T> {
386            fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
387                let bit_len = $crate::size_of::<$slice_ty>()*8;
388                let value_bit_len = $crate::size_of::<$bitrange_ty>()*8;
389                let mut value = 0;
390                for i in lsb..=msb {
391                    value <<= 1;
392                    value |= ((self.0.as_ref()[i/bit_len] >> (bit_len - i%bit_len - 1)) & 1)
393                        as $bitrange_ty;
394                }
395                value << (value_bit_len - (msb - lsb + 1)) >> (value_bit_len - (msb - lsb + 1))
396            }
397
398            fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
399                let bit_len = $crate::size_of::<$slice_ty>()*8;
400                let mut value = value;
401                for i in (lsb..=msb).rev() {
402                    self.0.as_mut()[i/bit_len] &= !(1 << (bit_len - i%bit_len - 1));
403                    self.0.as_mut()[i/bit_len] |= (value & 1) as $slice_ty
404                        << (bit_len - i%bit_len - 1);
405                    value >>= 1;
406                }
407            }
408        }
409    };
410    (struct $name:ident([$t:ty])) => {
411        bitfield_bitrange!(@impl_bitrange_slice $name, $t, u8);
412        bitfield_bitrange!(@impl_bitrange_slice $name, $t, u16);
413        bitfield_bitrange!(@impl_bitrange_slice $name, $t, u32);
414        bitfield_bitrange!(@impl_bitrange_slice $name, $t, u64);
415        bitfield_bitrange!(@impl_bitrange_slice $name, $t, u128);
416        bitfield_bitrange!(@impl_bitrange_slice $name, $t, i8);
417        bitfield_bitrange!(@impl_bitrange_slice $name, $t, i16);
418        bitfield_bitrange!(@impl_bitrange_slice $name, $t, i32);
419        bitfield_bitrange!(@impl_bitrange_slice $name, $t, i64);
420        bitfield_bitrange!(@impl_bitrange_slice $name, $t, i128);
421    };
422    (struct $name:ident(MSB0 [$t:ty])) => {
423        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u8);
424        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u16);
425        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u32);
426        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u64);
427        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, u128);
428        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i8);
429        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i16);
430        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i32);
431        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i64);
432        bitfield_bitrange!(@impl_bitrange_slice_msb0 $name, $t, i128);
433    };
434    (struct $name:ident($t:ty)) => {
435        impl<T> $crate::BitRange<T> for $name where $t: $crate::BitRange<T> {
436            fn bit_range(&self, msb: usize, lsb: usize) -> T {
437                self.0.bit_range(msb, lsb)
438            }
439            fn set_bit_range(&mut self, msb: usize, lsb: usize, value: T) {
440                self.0.set_bit_range(msb, lsb, value);
441            }
442        }
443    };
444}
445
446#[macro_export(local_inner_macros)]
503macro_rules! bitfield {
504    ($(#[$attribute:meta])* pub struct $($rest:tt)*) => {
505        bitfield!($(#[$attribute])* (pub) struct $($rest)*);
506    };
507    ($(#[$attribute:meta])* struct $($rest:tt)*) => {
508        bitfield!($(#[$attribute])* () struct $($rest)*);
509    };
510    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($($type:tt)*); impl Debug; no default BitRange; $($rest:tt)*) => {
513         bitfield!{$(#[$attribute])* ($($vis)*) struct $name($($type)*); no default BitRange; impl Debug; $($rest)*}
514     };
515
516    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty]); no default BitRange; impl Debug; $($rest:tt)*) => {
519        impl<T: AsMut<[$t]> + AsRef<[$t]> + $crate::fmt::Debug> $crate::fmt::Debug for $name<T> {
520            bitfield_debug!{struct $name; $($rest)*}
521        }
522
523        bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange;  $($rest)*}
524    };
525    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty]); no default BitRange; $($rest:tt)*) => {
526        $(#[$attribute])*
527        $($vis)* struct $name<T>(pub T);
528
529        impl<T: AsMut<[$t]> + AsRef<[$t]>> $name<T> {
530            bitfield_fields!{$($rest)*}
531        }
532    };
533    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident([$t:ty]); $($rest:tt)*) => {
534        bitfield_bitrange!(struct $name([$t]));
535        bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange; $($rest)*}
536    };
537
538    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident(MSB0 [$t:ty]); no default BitRange; $($rest:tt)*) => {
541        bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange; $($rest)*}
542    };
543    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident(MSB0 [$t:ty]); $($rest:tt)*) => {
544        bitfield_bitrange!(struct $name(MSB0 [$t]));
545        bitfield!{$(#[$attribute])* ($($vis)*) struct $name([$t]); no default BitRange; $($rest)*}
546    };
547
548    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); no default BitRange; impl Debug; $($rest:tt)*) => {
549        impl $crate::fmt::Debug for $name {
550            bitfield_debug!{struct $name; $($rest)*}
551        }
552
553        bitfield!{$(#[$attribute])* ($($vis)*) struct $name($t); no default BitRange; $($rest)*}
554    };
555    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); no default BitRange; $($rest:tt)*) => {
556        $(#[$attribute])*
557        $($vis)* struct $name(pub $t);
558
559        impl $name {
560            bitfield_fields!{$t; $($rest)*}
561         }
562    };
563    ($(#[$attribute:meta])* ($($vis:tt)*) struct $name:ident($t:ty); $($rest:tt)*) => {
564        bitfield_bitrange!(struct $name($t));
565        bitfield!{$(#[$attribute])* ($($vis)*) struct $name($t); no default BitRange; $($rest)*}
566    };
567}
568
569#[doc(hidden)]
570pub use core::convert::Into;
571#[doc(hidden)]
572pub use core::fmt;
573#[doc(hidden)]
574pub use core::mem::size_of;
575
576pub trait BitRange<T> {
578    fn bit_range(&self, msb: usize, lsb: usize) -> T;
580    fn set_bit_range(&mut self, msb: usize, lsb: usize, value: T);
582}
583
584pub trait Bit {
588    fn bit(&self, bit: usize) -> bool;
590
591    fn set_bit(&mut self, bit: usize, value: bool);
593}
594
595impl<T: BitRange<u8>> Bit for T {
596    fn bit(&self, bit: usize) -> bool {
597        self.bit_range(bit, bit) != 0
598    }
599    fn set_bit(&mut self, bit: usize, value: bool) {
600        self.set_bit_range(bit, bit, value as u8);
601    }
602}
603
604macro_rules! impl_bitrange_for_u {
605    ($t:ty, $bitrange_ty:ty) => {
606        impl BitRange<$bitrange_ty> for $t {
607            #[inline]
608            #[allow(unknown_lints)]
609            #[allow(cast_lossless)]
610            fn bit_range(&self, msb: usize, lsb: usize) -> $bitrange_ty {
611                let bit_len = size_of::<$t>()*8;
612                let result_bit_len = size_of::<$bitrange_ty>()*8;
613                let result = ((*self << (bit_len - msb - 1)) >> (bit_len - msb - 1 + lsb))
614                    as $bitrange_ty;
615                result << (result_bit_len - (msb - lsb + 1)) >> (result_bit_len - (msb - lsb + 1))
616            }
617
618            #[inline]
619            #[allow(unknown_lints)]
620            #[allow(cast_lossless)]
621            fn set_bit_range(&mut self, msb: usize, lsb: usize, value: $bitrange_ty) {
622                let bit_len = size_of::<$t>()*8;
623                let mask: $t = !(0 as $t)
624                    << (bit_len - msb - 1)
625                    >> (bit_len - msb - 1 + lsb)
626                    << (lsb);
627                *self &= !mask;
628                *self |= (value as $t << lsb) & mask;
629            }
630        }
631    }
632}
633
634macro_rules! impl_bitrange_for_u_combinations {
635((),($($bitrange_ty:ty),*)) => {
636
637};
638(($t:ty),($($bitrange_ty:ty),*)) => {
639        $(impl_bitrange_for_u!{$t, $bitrange_ty})*
640};
641    (($t_head:ty, $($t_rest:ty),*),($($bitrange_ty:ty),*)) => {
642        impl_bitrange_for_u_combinations!{($t_head), ($($bitrange_ty),*)}
643        impl_bitrange_for_u_combinations!{($($t_rest),*), ($($bitrange_ty),*)}
644    };
645}
646
647impl_bitrange_for_u_combinations! {(u8, u16, u32, u64, u128), (u8, u16, u32, u64, u128)}
648impl_bitrange_for_u_combinations! {(u8, u16, u32, u64, u128), (i8, i16, i32, i64, i128)}
649
650#[macro_export]
653#[doc(hidden)]
654macro_rules! __bitfield_stringify {
655    ($s:ident) => {
656        stringify!($s)
657    };
658}
659
660#[macro_export]
663#[doc(hidden)]
664macro_rules! __bitfield_debug_assert {
665    ($e:expr) => {
666        debug_assert!($e)
667    };
668}