bitfield_layout/
lib.rs

1//! This crate is yet another bitfield handling implementation.
2//! 
3//! The main goal of this crate - provide binding for various data to every bit (flag) within bitfield layout.
4//! In many cases bitfield data are read-only and every bit (flag) has some meaning.
5//! Then you getting bitfield data it's useful to get meaning and/or description of setted flags.
6//! 
7//! This crate provides basic trait [BitFieldLayout] that provides convenient methods for getting flags
8//! and it meanings of user defined structs or enums. Also there is module [layouts] with accessory
9//! structs and macros.
10//! 
11//! # Example: simple string
12//! Bits layout within bitfield may be associated with it meaning in many ways. The simple case - each
13//! bit (flag) has simple string description.
14//! 
15//! ```
16//! use std::{array, fmt, slice};
17//! use either::Either;
18//! use bitfield_layout::{Layout, BitFieldLayout};
19//! 
20//! // New struct that holds bitfield value
21//! struct Simple(u8);
22//! // Associated bit layout implementation
23//! impl Layout for Simple {
24//!     type Layout = slice::Iter<'static, &'static str>;
25//!     fn layout() -> Self::Layout {
26//!         [
27//!             "First flag", 
28//!             "Second flag", 
29//!             "Third flag", 
30//!             "Fourth flag", 
31//!             "Fifth flag", 
32//!             "Sixth flag", 
33//!             "Seventh flag", 
34//!             "Eighth flag", 
35//!         ].iter()
36//!     }
37//! }
38//! // Main trait implementation
39//! impl BitFieldLayout for Simple {
40//!     type Value = u8;
41//!     fn get(&self) -> Self::Value { self.0 }
42//!     fn set(&mut self, new: Self::Value) { self.0 = new; }
43//! }
44//! 
45//! // Now we can use methods provided by trait
46//! 
47//! // Show full data layout (just show flag meanings that we defined)
48//! let layout = Simple::layout();
49//!
50//! let layout_result = layout
51//!     .cloned()
52//!     .collect::<Vec<_>>();
53//! let layout_sample = vec![
54//!     "First flag",
55//!     "Second flag",
56//!     "Third flag",
57//!     "Fourth flag",
58//!     "Fifth flag",
59//!     "Sixth flag",
60//!     "Seventh flag",
61//!     "Eighth flag",
62//! ];
63//! assert_eq!(layout_sample, layout_result, "Layout");
64//! 
65//! // Assign value to aur bitfield type
66//! let simple = Simple(0b10101010);
67//! // Show every bit (flag) state
68//! let bits = simple.bits();
69//!
70//! let bits_result = bits
71//!     .enumerate()
72//!     .map(|(n, b)| format!("Bit #{}: {}", n, if b { "Is set" } else { "Not set" }))
73//!     .collect::<Vec<_>>();
74//! let bits_sample = vec![
75//!     "Bit #0: Not set",
76//!     "Bit #1: Is set",
77//!     "Bit #2: Not set",
78//!     "Bit #3: Is set",
79//!     "Bit #4: Not set",
80//!     "Bit #5: Is set",
81//!     "Bit #6: Not set",
82//!     "Bit #7: Is set",
83//! ];
84//! assert_eq!(bits_sample, bits_result, "Bits");
85//! 
86//! // Show bit (flag) state and it meaning
87//! let flags = simple.flags();
88//!
89//! let flags_result = flags
90//!     .map(|f| format!("`{}` is {}", f.value, f.is_set))
91//!     .collect::<Vec<_>>();
92//! let flags_sample = vec![
93//!     "`First flag` is false",
94//!     "`Second flag` is true",
95//!     "`Third flag` is false",
96//!     "`Fourth flag` is true",
97//!     "`Fifth flag` is false",
98//!     "`Sixth flag` is true",
99//!     "`Seventh flag` is false",
100//!     "`Eighth flag` is true",
101//! ];
102//! assert_eq!(flags_sample, flags_result, "Flags");
103//! 
104//! // Same as above, but using internal [Flag] Display trait
105//! let flags = simple.flags();
106//! let flags_str_result: String = flags
107//!     .map(|f| format!("{}", f))
108//!     .collect::<Vec<String>>()
109//!     .join(" ");
110//! let flags_str_sample = "-#0 +#1 -#2 +#3 -#4 +#5 -#6 +#7";
111//! assert_eq!(flags_str_sample, flags_str_result, "Flags");
112//!
113//! // Show difference between two bitfield values
114//! let other = Simple(0b11001100);
115//! let diff = simple.diff(other);
116//!
117//! let diff_result = diff
118//!     .collect::<Vec<_>>();
119//! let diff_sample = vec![
120//!     Either::Left((1, &"Second flag")),
121//!     Either::Right((2, &"Third flag")),
122//!     Either::Left((5, &"Sixth flag")),
123//!     Either::Right((6, &"Seventh flag")),
124//! ];
125//! assert_eq!(diff_sample, diff_result, "Diff");
126//! ```
127//! 
128//! # Example: status register of MOS Technology 6502
129//! One eight-bit field holds seven pieces of information:
130//! 
131//! Bit # | Name | Desription
132//! ------|------|-----------
133//!    0  | Carry flag | Enables numbers larger than a single word to be added/subtracted by carrying a binary digit from a less significant word to the least significant bit of a more significant word as needed.
134//!    1  | Zero flag | Indicates that the result of an arithmetic or logical operation (or, sometimes, a load) was zero.
135//!    2  | Interrupt flag | Indicates whether interrupts are enabled or masked.
136//!    3  | Decimal flag | Indicates that a bit carry was produced between the nibbles as a result of the last arithmetic operation.
137//!    4  | Break flag | It can be examined as a value stored on the stack.
138//!    5  | Unused | Unused
139//!    6  | Overflow flag | Indicates that the signed result of an operation is too large to fit in the register width using two's complement representation.
140//!    7  | Negative flag | Indicates that the result of a mathematical operation is negative.
141//! 
142//! We can handle this register like:
143//! ```
144//! use std::{array, fmt, slice};
145//! use bitfield_layout::{Layout, BitFieldLayout};
146//! 
147//! // Struct for handle flag name and flag description
148//! struct NameAndDescription<'a>(&'a str, &'a str);
149//! // Implement Display: Name for basic form "{}" and Description for alternative "{:#}"
150//! impl<'a> fmt::Display for NameAndDescription<'a> {
151//!     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
152//!         let s = if f.alternate() { self.1 } else { self.0 };
153//!         write!(f, "{}", s)
154//!     }
155//! }
156//! 
157//! // New struct that holds bitfield value
158//! struct StatusRegister(u8);
159//! // Associate bitfield layout with bitfield type
160//! impl StatusRegister {
161//!     const LAYOUT: [NameAndDescription<'static>; 8] = [
162//!         NameAndDescription(
163//!             "Carry flag",
164//!             "Enables numbers larger than a single word to be added/subtracted by \
165//!             carrying a binary digit from a less significant word to the least \
166//!             significant bit of a more significant word as needed."
167//!         ),
168//!         NameAndDescription(
169//!             "Zero flag",
170//!             "Indicates that the result of an arithmetic or logical operation \
171//!             (or, sometimes, a load) was zero."
172//!         ),
173//!         NameAndDescription(
174//!             "Interrupt flag",
175//!             "Indicates whether interrupts are enabled or masked."
176//!         ),
177//!         NameAndDescription(
178//!             "Decimal flag",
179//!             "Indicates that a bit carry was produced between the nibbles as a \
180//!             result of the last arithmetic operation."
181//!         ),
182//!         NameAndDescription(
183//!             "Break flag",
184//!             "It can be examined as a value stored on the stack."
185//!         ),
186//!         NameAndDescription("Unused", "Unused"),
187//!         NameAndDescription(
188//!             "Overflow flag",
189//!             "Indicates that the signed result of an operation is too large to \
190//!             fit in the register width using two's complement representation."
191//!         ),
192//!         NameAndDescription(
193//!             "Negative flag",
194//!             "Indicates that the result of a mathematical operation is negative."
195//!         ),
196//!     ];
197//! }
198//! 
199//! // Implement layout iterator
200//! impl Layout for StatusRegister {
201//!     type Layout = slice::Iter<'static, NameAndDescription<'static>>;
202//!     // Take bitfield layout from associated constant
203//!     fn layout() -> Self::Layout {
204//!         StatusRegister::LAYOUT.iter()
205//!     }
206//! }
207//! // Bitfield trait implementation
208//! impl BitFieldLayout for StatusRegister {
209//!     type Value = u8;
210//!     fn get(&self) -> Self::Value { self.0 }
211//!     fn set(&mut self, new: Self::Value) { self.0 = new; }
212//! }
213//! 
214//! // For example our value has setted Interrupt and Negative flags
215//! let status = StatusRegister(0b10000100);
216//! 
217//! let result = status.flags()
218//!     .filter(|f| f.is_set)
219//!     .map(|f| format!("Name: {}\nDescription: {:#}\n", f.value, f.value))
220//!     .collect::<Vec<_>>()
221//!     .join("\n");
222//! let sample = "\
223//! Name: Interrupt flag
224//! Description: Indicates whether interrupts are enabled or masked.
225//!
226//! Name: Negative flag
227//! Description: Indicates that the result of a mathematical operation is negative.
228//! ";
229//! assert_eq!(sample, result);
230//! ```
231//! 
232//! ---
233//! There are more examples in [layouts] and [BitField]
234
235
236
237
238#![no_std]
239
240use core::{array, fmt, iter, ops};
241
242use either::Either;
243
244#[macro_use]
245pub mod layouts;
246pub use layouts::*;
247
248
249/// Main trait for creating bitfield 
250///
251/// In general you need implement this trait and its dependencies: [Layout]. 
252/// This trait already implemented for [BitField].
253pub trait BitFieldLayout: Layout {
254    type Value: Copy + IntoBits + FromBits;
255    /// Returns a copy of the contained value.
256    fn get(&self) -> Self::Value;
257    /// Sets the contained value.
258    fn set(&mut self, new: Self::Value);
259
260    /// Replaces the contained value with val, and returns the old contained value.
261    /// ```
262    /// # use std::iter;
263    /// # use bitfield_layout::{BitFieldLayout, Layout};
264    /// # struct Simple(u16);
265    /// # impl Layout for Simple {
266    /// #     type Layout = iter::Empty<()>;
267    /// #     fn layout() -> Self::Layout { iter::empty() }
268    /// # }
269    /// # impl BitFieldLayout for Simple {
270    /// #     type Value = u16;
271    /// #     fn get(&self) -> Self::Value { self.0 }
272    /// #     fn set(&mut self, new: Self::Value) { self.0 = new; }
273    /// # }
274    /// let mut simple = Simple(42);
275    ///
276    /// assert_eq!(42, simple.replace(13));
277    /// assert_eq!(13, simple.get());
278    /// ```
279    fn replace(&mut self, new: Self::Value) -> Self::Value {
280        let v = self.get();
281        self.set(new);
282        v
283    }
284    /// Swaps the values of two bitfields.
285    /// ```
286    /// # use std::iter;
287    /// # use bitfield_layout::{BitFieldLayout, Layout};
288    /// # struct Simple(u16);
289    /// # impl Layout for Simple {
290    /// #     type Layout = iter::Empty<()>;
291    /// #     fn layout() -> Self::Layout { iter::empty() }
292    /// # }
293    /// # impl BitFieldLayout for Simple {
294    /// #     type Value = u16;
295    /// #     fn get(&self) -> Self::Value { self.0 }
296    /// #     fn set(&mut self, new: Self::Value) { self.0 = new; }
297    /// # }
298    /// let mut one = Simple(1);
299    /// let mut two = Simple(2);
300    ///
301    /// one.swap(&mut two);
302    ///
303    /// assert!(one.get() == 2 && two.get() == 1);
304    /// ```
305    fn swap(&mut self, other: &mut Self) {
306        let (a, b) = (self.get(), other.get());
307        self.set(b);
308        other.set(a);
309    }
310    /// Updates the contained value using a function and returns the new value.
311    /// ```
312    /// # use std::iter;
313    /// # use bitfield_layout::{BitFieldLayout, Layout};
314    /// # struct Simple(u64);
315    /// # impl Layout for Simple {
316    /// #     type Layout = iter::Empty<()>;
317    /// #     fn layout() -> Self::Layout { iter::empty() }
318    /// # }
319    /// # impl BitFieldLayout for Simple {
320    /// #     type Value = u64;
321    /// #     fn get(&self) -> Self::Value { self.0 }
322    /// #     fn set(&mut self, new: Self::Value) { self.0 = new; }
323    /// # }
324    /// let mut simple = Simple(1111111111);
325    ///
326    /// assert_eq!(2222222222, simple.update(|x| x * 2));
327    /// assert_eq!(2222222222, simple.get());
328    /// ```
329    fn update<F>(&mut self, f: F) -> Self::Value
330    where
331        F: FnOnce(Self::Value) -> Self::Value,
332    {
333        let v = f(self.get());
334        self.set(v);
335        self.get()
336    }
337
338    /// Set the specified bit (flag) in-place. Returns current state
339    /// ```
340    /// # use std::iter;
341    /// # use bitfield_layout::{BitFieldLayout, Layout};
342    /// # struct Simple(u64);
343    /// # impl Layout for Simple {
344    /// #     type Layout = iter::Empty<()>;
345    /// #     fn layout() -> Self::Layout { iter::empty() }
346    /// # }
347    /// # impl BitFieldLayout for Simple {
348    /// #     type Value = u64;
349    /// #     fn get(&self) -> Self::Value { self.0 }
350    /// #     fn set(&mut self, new: Self::Value) { self.0 = new; }
351    /// # }
352    /// let mut simple = Simple(0b10011001);
353    ///
354    /// assert_eq!(false, simple.insert_flag(2, true));
355    /// assert_eq!(0b10011101, simple.get());
356    /// ```
357    fn insert_flag(&mut self, position: usize, b: bool) -> bool {
358        let mut result = false;
359        let bits = self.get()
360            .into_bits()
361            .enumerate()
362            .map(|(n, is_set)| {
363                if n == position {
364                    result = is_set;
365                    b
366                } else {
367                    is_set
368                }
369            });
370        self.set(Self::Value::from_bits(bits));
371        result
372    }
373    /// The specified bit (flag) will be inverted
374    /// ```
375    /// # use std::iter;
376    /// # use bitfield_layout::{BitFieldLayout, Layout};
377    /// # struct Simple(u64);
378    /// # impl Layout for Simple {
379    /// #     type Layout = iter::Empty<()>;
380    /// #     fn layout() -> Self::Layout { iter::empty() }
381    /// # }
382    /// # impl BitFieldLayout for Simple {
383    /// #     type Value = u64;
384    /// #     fn get(&self) -> Self::Value { self.0 }
385    /// #     fn set(&mut self, new: Self::Value) { self.0 = new; }
386    /// # }
387    /// let mut simple = Simple(0b10011001);
388    ///
389    /// simple.toggle_flag(0);
390    ///
391    /// assert_eq!(0b10011000, simple.get());
392    /// ```
393    fn toggle_flag(&mut self, position: usize) {
394        let bits = self.get()
395            .into_bits()
396            .enumerate()
397            .map(|(n, is_set)| {
398                if n == position {
399                    !is_set
400                } else {
401                    is_set
402                }
403            });
404        self.set(Self::Value::from_bits(bits));
405    }
406    /// Return iterator through bitfield value bits. Every bit represents as bool value.
407    /// ```
408    /// # use std::iter;
409    /// # use bitfield_layout::{BitFieldLayout, Layout};
410    /// # struct Simple(u8);
411    /// # impl Layout for Simple {
412    /// #     type Layout = iter::Empty<()>;
413    /// #     fn layout() -> Self::Layout { iter::empty() }
414    /// # }
415    /// # impl BitFieldLayout for Simple {
416    /// #     type Value = u8;
417    /// #     fn get(&self) -> Self::Value { self.0 }
418    /// #     fn set(&mut self, new: Self::Value) { self.0 = new; }
419    /// # }
420    /// let mut simple = Simple(0b01010101);
421    ///
422    /// assert!(simple.bits().step_by(2).all(|v| v == true));
423    /// ```
424    fn bits(&self) -> Bits<<Self::Value as IntoBits>::Bytes> {
425        self.get().into_bits()
426    }
427    /// Return iterator through bitfield value flags. Every flag contains bit state (set or unset)
428    /// and item (record) value - string in simple case.
429    /// ```
430    /// # use std::{iter, slice};
431    /// # use bitfield_layout::{BitFieldLayout, Flag, Layout};
432    /// struct Simple(u8);
433    /// impl Layout for Simple {
434    ///     type Layout = slice::Iter<'static, &'static str>;
435    ///     fn layout() -> Self::Layout {
436    ///         [
437    ///             "First",
438    ///             "Second",
439    ///             "Third",
440    ///             "Fourth",
441    ///             "Fifth",
442    ///             "Sixth",
443    ///             "Seventh",
444    ///             "Eighth",
445    ///         ].iter()
446    ///     }
447    /// }
448    /// # impl BitFieldLayout for Simple {
449    /// #     type Value = u8;
450    /// #     fn get(&self) -> Self::Value { self.0 }
451    /// #     fn set(&mut self, new: Self::Value) { self.0 = new; }
452    /// # }
453    /// let mut simple = Simple(0b01010101);
454    ///
455    /// assert_eq!(Flag { position: 0, is_set: true, value: &"First"}, simple.flags().next().unwrap());
456    /// ```
457    fn flags(&self) -> Flags<Self::Layout, Bits<<Self::Value as IntoBits>::Bytes>> {
458        Flags::new(Self::layout(), self.bits())
459    }
460    /// Helps to find difference between two bitfield values.
461    /// ```
462    /// # use std::{iter, slice};
463    /// # use either::Either;
464    /// # use bitfield_layout::{BitFieldLayout, Flag, Layout};
465    /// struct Simple(u8);
466    /// impl Layout for Simple {
467    ///     type Layout = slice::Iter<'static, &'static str>;
468    ///     fn layout() -> Self::Layout {
469    ///         [
470    ///             "First",
471    ///             "Second",
472    ///             "Third",
473    ///             "Fourth",
474    ///             "Fifth",
475    ///             "Sixth",
476    ///             "Seventh",
477    ///             "Eighth",
478    ///         ].iter()
479    ///     }
480    /// }
481    /// # impl BitFieldLayout for Simple {
482    /// #     type Value = u8;
483    /// #     fn get(&self) -> Self::Value { self.0 }
484    /// #     fn set(&mut self, new: Self::Value) { self.0 = new; }
485    /// # }
486    /// let mut left =  Simple(0b01010101);
487    /// let mut right = Simple(0b01010001);
488    ///
489    /// assert_eq!(vec![Either::Left((2, &"Third"))], left.diff(right).collect::<Vec<_>>());
490    /// ```
491    fn diff(&self, other: Self) -> Diff<Self::Layout, Bits<<Self::Value as IntoBits>::Bytes>>
492    where
493        Self: Sized,
494    {
495        Diff::new(self.flags(), other.flags())
496    }
497    /// Find specific flag state. [None] if not find
498    /// ```
499    /// # use std::{iter, slice};
500    /// # use either::Either;
501    /// # use bitfield_layout::{BitFieldLayout, Flag, Layout};
502    /// struct Simple(u8);
503    /// impl Layout for Simple {
504    ///     type Layout = slice::Iter<'static, &'static str>;
505    ///     fn layout() -> Self::Layout {
506    ///         [
507    ///             "First",
508    ///             "Second",
509    ///             "Third",
510    ///             "Fourth",
511    ///             "Fifth",
512    ///             "Sixth",
513    ///             "Seventh",
514    ///             "Eighth",
515    ///         ].iter()
516    ///     }
517    /// }
518    /// # impl BitFieldLayout for Simple {
519    /// #     type Value = u8;
520    /// #     fn get(&self) -> Self::Value { self.0 }
521    /// #     fn set(&mut self, new: Self::Value) { self.0 = new; }
522    /// # }
523    /// let mut simple =  Simple(0b01010101);
524    ///
525    /// assert_eq!(Some(true), simple.find_state(|v| v == &"Third"));
526    /// assert_eq!(None, simple.find_state(|v| v == &"Thirddd"));
527    /// ```
528    fn find_state<P>(&self, predicate: P) -> Option<bool>
529    where
530        //P: FnMut(<&<Self as Layout>::Layout as core::iter::Iterator>::Item) -> bool,
531        P: Fn(<<Self as Layout>::Layout as Iterator>::Item) -> bool,
532    {
533        for f in self.flags() {
534            if predicate(f.value) {
535                return Some(f.is_set)
536            }
537        }
538        None
539    }
540}
541
542/// Associated bits layout
543pub trait Layout {
544    /// Layout iterator. Typically constant array or slice
545    type Layout: Iterator;
546    /// Return iterator through layout items. Actual layout may be implemented inside this
547    /// function or be a associated constant of bitfield type
548    fn layout() -> Self::Layout;
549}
550
551
552/// Converts value to bit iterator
553pub trait IntoBits {
554    type Bytes: Iterator<Item = u8>;
555    fn into_bits(self) -> Bits<Self::Bytes>;
556}
557impl IntoBits for u8 {
558    type Bytes = array::IntoIter<u8, 1>;
559    fn into_bits(self) -> Bits<Self::Bytes> {
560        self.to_ne_bytes().into_bits()
561    }
562}
563impl IntoBits for u16 {
564    type Bytes = array::IntoIter<u8, 2>;
565    fn into_bits(self) -> Bits<Self::Bytes> {
566        self.to_ne_bytes().into_bits()
567    }
568}
569impl IntoBits for u32 {
570    type Bytes = array::IntoIter<u8, 4>;
571    fn into_bits(self) -> Bits<Self::Bytes> {
572        self.to_ne_bytes().into_bits()
573    }
574}
575impl IntoBits for u64 {
576    type Bytes = array::IntoIter<u8, 8>;
577    fn into_bits(self) -> Bits<Self::Bytes> {
578        self.to_ne_bytes().into_bits()
579    }
580}
581impl IntoBits for u128 {
582    type Bytes = array::IntoIter<u8, 16>;
583    fn into_bits(self) -> Bits<Self::Bytes> {
584        self.to_ne_bytes().into_bits()
585    }
586}
587impl<const N: usize> IntoBits for [u8; N] {
588    type Bytes = array::IntoIter<u8, N>;
589    fn into_bits(self) -> Bits<Self::Bytes> {
590        Bits::new(array::IntoIter::new(self))
591    }
592}
593
594// At moment const expression can not contain the generic parameter,
595// so we can not just define [u8; { M * N }] array.
596// To implement IntoBits for [u16; N], [u32; N], [u64; N] and [u128; N] we will
597// use some tricks.
598impl<const N: usize> IntoBits for [u16; N] {
599    type Bytes = iter::Flatten<array::IntoIter<array::IntoIter<u8, N>, 2>>;
600    fn into_bits(self) -> Bits<Self::Bytes> {
601        // array::IntoIter has no Copy trait, so we will use copypaste method
602        let mut result = [
603            array::IntoIter::new([0u8; N]),
604            array::IntoIter::new([0u8; N]),
605        ];
606        let mut buf = [0u8; N];
607        let bytes = self.iter()
608            .map(|d| array::IntoIter::new(d.to_ne_bytes()))
609            .flatten();
610        for (n, byte) in bytes.enumerate() {
611            let i = n % N;
612            buf[i] = byte;
613            if i == N - 1 {
614                result[n / N] = array::IntoIter::new(buf);
615            }
616        }
617        Bits::new(array::IntoIter::new(result).flatten())
618    }
619}
620impl<const N: usize> IntoBits for [u32; N] {
621    type Bytes = iter::Flatten<array::IntoIter<array::IntoIter<u8, N>, 4>>;
622    fn into_bits(self) -> Bits<Self::Bytes> {
623        // array::IntoIter has no Copy trait, so we will use copypaste method
624        let mut result = [
625            array::IntoIter::new([0u8; N]),
626            array::IntoIter::new([0u8; N]),
627            array::IntoIter::new([0u8; N]),
628            array::IntoIter::new([0u8; N]),
629        ];
630        let mut buf = [0u8; N];
631        let bytes = self.iter()
632            .map(|d| array::IntoIter::new(d.to_ne_bytes()))
633            .flatten();
634        for (n, byte) in bytes.enumerate() {
635            let i = n % N;
636            buf[i] = byte;
637            if i == N - 1 {
638                result[n / N] = array::IntoIter::new(buf);
639            }
640        }
641        Bits::new(array::IntoIter::new(result).flatten())
642    }
643}
644impl<const N: usize> IntoBits for [u64; N] {
645    type Bytes = iter::Flatten<array::IntoIter<array::IntoIter<u8, N>, 8>>;
646    fn into_bits(self) -> Bits<Self::Bytes> {
647        // array::IntoIter has no Copy trait, so we will use copypaste method
648        let mut result = [
649            array::IntoIter::new([0u8; N]),
650            array::IntoIter::new([0u8; N]),
651            array::IntoIter::new([0u8; N]),
652            array::IntoIter::new([0u8; N]),
653            array::IntoIter::new([0u8; N]),
654            array::IntoIter::new([0u8; N]),
655            array::IntoIter::new([0u8; N]),
656            array::IntoIter::new([0u8; N]),
657        ];
658        let mut buf = [0u8; N];
659        let bytes = self.iter()
660            .map(|d| array::IntoIter::new(d.to_ne_bytes()))
661            .flatten();
662        for (n, byte) in bytes.enumerate() {
663            let i = n % N;
664            buf[i] = byte;
665            if i == N - 1 {
666                result[n / N] = array::IntoIter::new(buf);
667            }
668        }
669        Bits::new(array::IntoIter::new(result).flatten())
670    }
671}
672impl<const N: usize> IntoBits for [u128; N] {
673    type Bytes = iter::Flatten<array::IntoIter<array::IntoIter<u8, N>, 16>>;
674    fn into_bits(self) -> Bits<Self::Bytes> {
675        // array::IntoIter has no Copy trait, so we will use copypaste method
676        let mut result = [
677            array::IntoIter::new([0u8; N]),
678            array::IntoIter::new([0u8; N]),
679            array::IntoIter::new([0u8; N]),
680            array::IntoIter::new([0u8; N]),
681            array::IntoIter::new([0u8; N]),
682            array::IntoIter::new([0u8; N]),
683            array::IntoIter::new([0u8; N]),
684            array::IntoIter::new([0u8; N]),
685            array::IntoIter::new([0u8; N]),
686            array::IntoIter::new([0u8; N]),
687            array::IntoIter::new([0u8; N]),
688            array::IntoIter::new([0u8; N]),
689            array::IntoIter::new([0u8; N]),
690            array::IntoIter::new([0u8; N]),
691            array::IntoIter::new([0u8; N]),
692            array::IntoIter::new([0u8; N]),
693        ];
694        let mut buf = [0u8; N];
695        let bytes = self.iter()
696            .map(|d| array::IntoIter::new(d.to_ne_bytes()))
697            .flatten();
698        for (n, byte) in bytes.enumerate() {
699            let i = n % N;
700            buf[i] = byte;
701            if i == N - 1 {
702                result[n / N] = array::IntoIter::new(buf);
703            }
704        }
705        Bits::new(array::IntoIter::new(result).flatten())
706    }
707}
708
709/// Converts bit iterator to value
710pub trait FromBits {
711    fn from_bits<I: Iterator<Item = bool>>(bits: I) -> Self;
712}
713impl FromBits for u8 {
714    fn from_bits<I: Iterator<Item = bool>>(bits: I) -> Self {
715        u8::from_ne_bytes(<[u8; 1]>::from_bits(bits))
716    }
717}
718impl FromBits for u16 {
719    fn from_bits<I: Iterator<Item = bool>>(bits: I) -> Self {
720        u16::from_ne_bytes(<[u8; 2]>::from_bits(bits))
721    }
722}
723impl FromBits for u32 {
724    fn from_bits<I: Iterator<Item = bool>>(bits: I) -> Self {
725        u32::from_ne_bytes(<[u8; 4]>::from_bits(bits))
726    }
727}
728impl FromBits for u64 {
729    fn from_bits<I: Iterator<Item = bool>>(bits: I) -> Self {
730        u64::from_ne_bytes(<[u8; 8]>::from_bits(bits))
731    }
732}
733impl FromBits for u128 {
734    fn from_bits<I: Iterator<Item = bool>>(bits: I) -> Self {
735        u128::from_ne_bytes(<[u8; 16]>::from_bits(bits))
736    }
737}
738impl<const N: usize> FromBits for [u8; N] {
739    fn from_bits<I: Iterator<Item = bool>>(bits: I) -> Self {
740        let mut result = [0u8; N];
741        for (i, is_set) in bits.enumerate().take(N * 8) {
742            if is_set {
743                result[i / 8] |= 1 << (i % 8)
744            }
745        }
746        result
747    }
748}
749impl<const N: usize> FromBits for [u16; N] {
750    fn from_bits<I: Iterator<Item = bool>>(bits: I) -> Self {
751        <[[u8; 2]; N]>::from_bits(bits).iter()
752            .map(|arr| u16::from_ne_bytes(*arr))
753            .enumerate()
754            .fold([0; N], |mut result, (n, v)| { result[n] = v; result })
755    }
756}
757impl<const N: usize> FromBits for [u32; N] {
758    fn from_bits<I: Iterator<Item = bool>>(bits: I) -> Self {
759        <[[u8; 4]; N]>::from_bits(bits).iter()
760            .map(|arr| u32::from_ne_bytes(*arr))
761            .enumerate()
762            .fold([0; N], |mut result, (n, v)| { result[n] = v; result })
763    }
764}
765impl<const N: usize> FromBits for [u64; N] {
766    fn from_bits<I: Iterator<Item = bool>>(bits: I) -> Self {
767        <[[u8; 8]; N]>::from_bits(bits).iter()
768            .map(|arr| u64::from_ne_bytes(*arr))
769            .enumerate()
770            .fold([0; N], |mut result, (n, v)| { result[n] = v; result })
771    }
772}
773impl<const N: usize> FromBits for [u128; N] {
774    fn from_bits<I: Iterator<Item = bool>>(bits: I) -> Self {
775        <[[u8; 16]; N]>::from_bits(bits).iter()
776            .map(|arr| u128::from_ne_bytes(*arr))
777            .enumerate()
778            .fold([0; N], |mut result, (n, v)| { result[n] = v; result })
779    }
780}
781impl<const N: usize, const M: usize> FromBits for [[u8; N]; M] {
782    fn from_bits<I: Iterator<Item = bool>>(bits: I) -> Self {
783        let mut result = [[0u8; N]; M];
784        for (i, is_set) in bits.enumerate().take(N * M * 8) {
785            if is_set {
786                let m = (i / 8) % M;
787                let n = (i / 8) % N;
788                result[m][n] |= 1 << (i % 8)
789            }
790        }
791        result
792    }
793}
794
795/// An iterator through value bits
796#[derive(Debug, Clone, Copy)]
797pub struct Bits<I> {
798    iter: I,
799    byte: u8,
800    position: usize
801}
802impl<I: Iterator<Item = u8>> Bits<I> {
803    pub fn new(iter: I) -> Self {
804        Self { iter, byte: 0, position: 0 }
805    }
806}
807impl<I: Iterator<Item = u8>> Iterator for Bits<I> {
808    type Item = bool;
809
810    fn next(&mut self) -> Option<Self::Item> {
811        if self.position == 0 {
812            self.byte = self.iter.next()?;
813        }
814        let position = self.position;
815        self.position = (self.position + 1) % 8;
816        Some(self.byte & (1 << position) != 0)
817    }
818}
819
820/// Handle flag's position, state and value
821#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
822pub struct Flag<T> {
823    pub position: usize,
824    pub is_set: bool,
825    pub value: T,
826}
827/// Simple formatting: **+** for setted flag and **-** otherwise
828impl<T> fmt::Display for Flag<T> {
829    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
830        write!(f, "{}#{}", if self.is_set { "+" } else { "-" }, self.position)
831    }
832}
833
834/// An iterator through [Flag]s
835#[derive(Debug, Clone)]
836pub struct Flags<L, B>
837where
838    L: Iterator,
839    B: Iterator<Item = bool>
840{
841    position: usize,
842    layout: L,
843    bits: B,
844}
845impl<L, B> Flags<L, B>
846where
847    L: Iterator,
848    B: Iterator<Item = bool>
849{
850    pub fn new(layout: L, bits: B) -> Self {
851        Self { position: 0, layout, bits, }
852    }
853}
854impl<L, B> Iterator for Flags<L, B>
855where
856    L: Iterator,
857    B: Iterator<Item = bool>
858{
859    type Item = Flag<L::Item>;
860
861    fn next(&mut self) -> Option<Self::Item> {
862        let value = self.layout.next()?;
863        let is_set = self.bits.next()?;
864        let position = self.position;
865        self.position += 1;
866        Some(Flag { position, is_set, value })
867    }
868}
869
870/// An iterator through non equal flags
871#[derive(Debug, Clone)]
872pub struct Diff<L, B>
873where
874    L: Iterator,
875    B: Iterator<Item = bool>
876{
877    left: Flags<L, B>,
878    right: Flags<L, B>,
879    position: usize,
880}
881impl<L, B> Diff<L, B>
882where
883    L: Iterator,
884    B: Iterator<Item = bool>
885{
886    fn new(left: Flags<L, B>, right: Flags<L, B>) -> Self {
887        Self { left, right, position: 0 }
888    }
889}
890impl<L, T, B> Iterator for Diff<L, B>
891where
892    L: Iterator<Item = T>,
893    B: Iterator<Item = bool>
894{
895    type Item = Either<(usize, T), (usize, T)>;
896
897    fn next(&mut self) -> Option<Self::Item> {
898        loop {
899            let left = self.left.next()?;
900            let right = self.right.next()?;
901            let position = self.position;
902            self.position += 1;
903            match (left.is_set, right.is_set) {
904                (true, false) =>
905                    return Some(Either::Left((position, left.value))),
906                (false, true) =>
907                    return Some(Either::Right((position, right.value))),
908                _ => continue,
909            }
910        }
911    }
912}
913
914/// Accessory struct for convinient type construction
915///
916/// This structure holds value of created bitfield type and may be used for types that doesn't has
917/// own value field: enums and unit-like structs.
918///
919/// ## Enum wrapper
920/// Using enumeration as bitfield type has the following advantage - you can bind bit (flag) to one of
921/// enum variants.
922/// ```
923/// # use std::{array, fmt, slice};
924/// # use bitfield_layout::{BitFieldLayout, BitField, Layout};
925/// 
926/// // Declare new bitfield type
927/// enum EightFlags {
928///     One,
929///     Two,
930///     Three,
931///     Four,
932///     OemReserved(u8), // Reserved field referenced to multiple bits
933///     FutureReserved(u8), // Reserved field referenced to multiple bits
934/// }
935/// // Implement Dispaly trait for basic and alternative views
936/// impl fmt::Display for EightFlags {
937///     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
938///         match (self, f.alternate()) {
939///             // Basic view
940///             (Self::One,   false) => write!(f, "one"),
941///             (Self::Two,   false) => write!(f, "two"),
942///             (Self::Three, false) => write!(f, "three"),
943///             (Self::Four,  false) => write!(f, "four"),
944///             // Alternative view
945///             (Self::One,   true)  => write!(f, "ONE"),
946///             (Self::Two,   true)  => write!(f, "TWO"),
947///             (Self::Three, true)  => write!(f, "THREE"),
948///             (Self::Four,  true)  => write!(f, "FOUR"),
949///             // Reserved fields
950///             (Self::OemReserved(v), _) => write!(f, "OEM reserved (#{})", v),
951///             (Self::FutureReserved(v), _) => write!(f, "Reserved for future usage (#{})", v),
952///         }
953///     }
954/// }
955/// // Implement constant bit layout for this type
956/// impl EightFlags {
957///     const LAYOUT: [Self; 8] = [
958///         Self::One,
959///         Self::Two,
960///         Self::Three,
961///         Self::Four,
962///         Self::OemReserved(4),
963///         Self::OemReserved(5),
964///         Self::FutureReserved(6),
965///         Self::FutureReserved(7),
966///     ];
967/// }
968/// // Implement Layout for enum created early
969/// impl Layout for EightFlags {
970///     type Layout = std::slice::Iter<'static, EightFlags>;
971///     fn layout() -> Self::Layout { EightFlags::LAYOUT.iter() }
972/// }
973/// 
974/// // Now we can use wrapped bitfield enum
975/// let bf: BitField<EightFlags, u8> = BitField::new(0b01100101);
976/// 
977/// // Get only setted flags
978/// let result = bf.flags()
979///     .filter_map(|f| {
980///         if f.is_set {
981///             match f.value {
982///                 EightFlags::OemReserved(v) =>
983///                     Some(format!("Reserved flag #{}", v)),
984///                 EightFlags::FutureReserved(_) =>
985///                     Some(format!("{}", f.value)),
986///                 v @ _ =>
987///                     Some(format!("Name: {}, Description: {:#}", v, v)),
988///             }
989///         } else {
990///             None
991///         }
992///     })
993///     .collect::<Vec<_>>();
994/// 
995/// let sample = vec![
996///     "Name: one, Description: ONE",
997///     "Name: three, Description: THREE",
998///     "Reserved flag #5",
999///     "Reserved for future usage (#6)",
1000/// ];
1001/// assert_eq!(sample, result, "Wrapped enum");
1002/// ```
1003/// ## Unit-like struct wrapper
1004/// We can use bitfield type defined as unit-like struct in the same way as for
1005/// [enum](#enum-wrapper)
1006/// ```
1007/// # use std::{array, fmt, slice};
1008/// # use bitfield_layout::{BitFieldLayout, BitField, Layout};
1009/// 
1010/// // Unit-like struct without value
1011/// struct Status;
1012/// // Bind flags layout to this struct
1013/// impl Status {
1014///     const LAYOUT: [&'static str; 8] = [
1015///         "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1016///     ];
1017/// }
1018/// // Implement layout trait
1019/// impl Layout for Status {
1020///     type Layout = core::slice::Iter<'static, &'static str>;
1021///     fn layout() -> Self::Layout { Status::LAYOUT.iter() }
1022/// }
1023/// 
1024/// let bf: BitField<Status, u8> = BitField::new(42);
1025/// // Get formatted strings from flags iteartor
1026/// let result = bf.flags()
1027///     .map(|f| format!("{:#}", f.value))
1028///     .collect::<Vec<_>>();
1029/// let sample = vec!["s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7"];
1030/// assert_eq!(sample, result, "Simple unit-like struct");
1031/// 
1032/// ```
1033/// ## Unit-like struct with associated constants
1034/// Also we can use unit-like struct with associated constant flags. This will gave us feauture to has
1035/// marked bits. This realisation somewhere in beetween enum and simple unit-like struct.
1036/// ```
1037/// # use std::{array, fmt, slice};
1038/// # use bitfield_layout::{BitFieldLayout, BitField, Layout};
1039/// 
1040/// 
1041/// // Unit-like struct without value
1042/// struct Status;
1043/// // Implement layout. You can leave comments on every item. For example, you can use bit id as
1044/// // Status::ONE.
1045/// impl Status {
1046///     const ONE: &'static str = "One";
1047///     const TWO: &'static str = "Two";
1048///     const THREE: &'static str = "Three";
1049///     const FOUR: &'static str = "Four";
1050///     const RESERVED: &'static str = "Reserved";
1051///     const UNKNOWN: &'static str = "Unknown";
1052/// 
1053///     const LAYOUT: [&'static str; 8] = [
1054///         Self::ONE,
1055///         Self::TWO,
1056///         Self::THREE,
1057///         Self::FOUR,
1058///         Self::RESERVED,
1059///         Self::RESERVED,
1060///         Self::RESERVED,
1061///         Self::UNKNOWN,
1062///     ];
1063/// }
1064/// // Implement layout trait
1065/// impl Layout for Status {
1066///     type Layout = core::slice::Iter<'static, &'static str>;
1067///     fn layout() -> Self::Layout { Status::LAYOUT.iter() }
1068/// }
1069/// 
1070/// let bf: BitField<Status, u8> = BitField::new(0b00001000);
1071/// let result = bf.flags()
1072///     .find(|f| f.is_set)
1073///     .map(|f| f.value)
1074///     .unwrap();
1075/// assert_eq!(Status::FOUR, *result, "Enumeration");
1076/// ```
1077#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
1078pub struct BitField<M, T> {
1079    _marker: core::marker::PhantomData<M>,
1080    pub value: T,
1081}
1082impl<M, T> BitField<M, T> {
1083    pub fn new(value: T) -> Self {
1084        Self {
1085            _marker: core::marker::PhantomData,
1086            value
1087        }
1088    }
1089}
1090impl<M: Layout, T> Layout for BitField<M, T> {
1091    type Layout = M::Layout;
1092    fn layout() -> Self::Layout { M::layout() }
1093}
1094impl<M: Layout, T: Copy + IntoBits + FromBits> BitFieldLayout for BitField<M, T> {
1095    type Value = T;
1096    fn get(&self) -> Self::Value { self.value }
1097    fn set(&mut self, new: Self::Value) { self.value = new; }
1098}
1099impl<M, T> ops::BitAnd for BitField<M, T>
1100where
1101    M: Layout,
1102    T: Copy + IntoBits + FromBits + ops::BitAnd<Output = T>,
1103{
1104    type Output = Self;
1105    fn bitand(self, rhs: Self) -> Self::Output {
1106        Self::new(self.get() & rhs.get())
1107    }
1108}
1109impl<M, T> ops::BitAndAssign for BitField<M, T>
1110where
1111    M: Layout,
1112    T: Copy + IntoBits + FromBits + ops::BitAnd<Output = T>,
1113{
1114    fn bitand_assign(&mut self, rhs: Self) {
1115        *self = Self::new(self.get() & rhs.get())
1116    }
1117}
1118impl<M, T> ops::BitOr for BitField<M, T>
1119where
1120    M: Layout,
1121    T: Copy + IntoBits + FromBits + ops::BitOr<Output = T>,
1122{
1123    type Output = Self;
1124    fn bitor(self, rhs: Self) -> Self::Output {
1125        Self::new(self.get() | rhs.get())
1126    }
1127}
1128impl<M, T> ops::BitOrAssign for BitField<M, T>
1129where
1130    M: Layout,
1131    T: Copy + IntoBits + FromBits + ops::BitOr<Output = T>,
1132{
1133    fn bitor_assign(&mut self, rhs: Self) {
1134        *self = Self::new(self.get() | rhs.get())
1135    }
1136}
1137impl<M, T> ops::BitXor for BitField<M, T>
1138where
1139    M: Layout,
1140    T: Copy + IntoBits + FromBits + ops::BitXor<Output = T>,
1141{
1142    type Output = Self;
1143    fn bitxor(self, rhs: Self) -> Self::Output {
1144        Self::new(self.get() ^ rhs.get())
1145    }
1146}
1147impl<M, T> ops::BitXorAssign for BitField<M, T>
1148where
1149    M: Layout,
1150    T: Copy + IntoBits + FromBits + ops::BitXor<Output = T>,
1151{
1152    fn bitxor_assign(&mut self, rhs: Self) {
1153        *self = Self::new(self.get() ^ rhs.get())
1154    }
1155}
1156
1157
1158
1159#[cfg(test)]
1160#[macro_use]
1161extern crate std;
1162
1163#[cfg(test)]
1164mod tests {
1165    use std::prelude::v1::*;
1166    use pretty_assertions::assert_eq;
1167    use super::*;
1168
1169    #[test]
1170    fn bits() {
1171        let bits = Bits::new([13,42].iter().cloned());
1172        let sample = vec![
1173            true, false, true, true, false, false, false, false,
1174            false, true, false, true, false, true, false, false,
1175        ];
1176        let result = bits.collect::<Vec<_>>();
1177        assert_eq!(sample, result, "Bits");
1178    }
1179
1180    #[test]
1181    fn into_bits() {
1182        assert_eq!(vec![false,true,false,true], 42u8.into_bits().take(4).collect::<Vec<_>>(), "u8");
1183        assert_eq!(vec![false,true,false,true], 42u16.into_bits().take(4).collect::<Vec<_>>(), "u16");
1184        assert_eq!(vec![false,true,false,true], 42u32.into_bits().take(4).collect::<Vec<_>>(), "u32");
1185        assert_eq!(vec![false,true,false,true], 42u64.into_bits().take(4).collect::<Vec<_>>(), "u64");
1186        assert_eq!(vec![false,true,false,true], 42u128.into_bits().take(4).collect::<Vec<_>>(), "u128");
1187        assert_eq!(vec![false,true,false,true], [42u8,1,2].into_bits().take(4).collect::<Vec<_>>(), "[u8;3]");
1188        assert_eq!(vec![false,true,false,true], [42u16,1,2].into_bits().take(4).collect::<Vec<_>>(), "[u16;3]");
1189        assert_eq!(vec![false,true,false,true], [42u32,1,2].into_bits().take(4).collect::<Vec<_>>(), "[u32;3]");
1190        assert_eq!(vec![false,true,false,true], [42u64,1,2].into_bits().take(4).collect::<Vec<_>>(), "[u64;3]");
1191        assert_eq!(vec![false,true,false,true], [42u128,1,2].into_bits().take(4).collect::<Vec<_>>(), "[u128;3]");
1192    }
1193
1194    #[test]
1195    fn from_bits() {
1196        assert_eq!(42, u8::from_bits(42u8.into_bits()), "u8");
1197        assert_eq!(42, u16::from_bits(42u16.into_bits()), "u16");
1198        assert_eq!(42, u32::from_bits(42u32.into_bits()), "u32");
1199        assert_eq!(42, u64::from_bits(42u64.into_bits()), "u64");
1200        assert_eq!(42, u128::from_bits(42u128.into_bits()), "u128");
1201        assert_eq!([42;3], <[u8;3]>::from_bits([42u8;3].into_bits()), "[u8;3]");
1202        assert_eq!([42;3], <[u16;3]>::from_bits([42u16;3].into_bits()), "[u16;3]");
1203        assert_eq!([42;3], <[u32;3]>::from_bits([42u32;3].into_bits()), "[u32;3]");
1204        assert_eq!([42;3], <[u64;3]>::from_bits([42u64;3].into_bits()), "[u64;3]");
1205        assert_eq!([42;3], <[u128;3]>::from_bits([42u128;3].into_bits()), "[u128;3]");
1206    }
1207
1208    #[test]
1209    fn flags() {
1210        let flags = Flags::new(
1211            ["Flag 1","Flag 2","Flag 3","Flag 4","Flag 5","Flag 6","Flag 7","Flag 8",]
1212                .iter(),
1213            [ false,   true,    false,   true,    true,    false,   false,   false, ]
1214                .iter().cloned(),
1215        );
1216        let sample = vec!["Flag 2","Flag 4","Flag 5",];
1217        let result = flags.filter_map(|f| Some(*f.value).filter(|_| f.is_set)).collect::<Vec<_>>();
1218        assert_eq!(sample, result, "Flags");
1219    }
1220
1221    #[test]
1222    fn diff() {
1223        let layout = ["Flag 1","Flag 2","Flag 3","Flag 4","Flag 5","Flag 6","Flag 7","Flag 8",];
1224        let flags0 = Flags::new(
1225            layout.iter(),
1226            [ false,   true,    false,   true,    true,    false,   false,   false, ]
1227                .iter().cloned(),
1228        );
1229        let flags1 = Flags::new(
1230            layout.iter(),
1231            [ false,   true,    false,   false,    true,    false,   true,   false, ]
1232                .iter().cloned(),
1233        );
1234        let sample = vec![
1235            Either::Left((3, &"Flag 4")),
1236            Either::Right((6, &"Flag 7"))
1237        ];
1238        let result = Diff::new(flags0, flags1).collect::<Vec<_>>();
1239        assert_eq!(sample, result, "Diff");
1240    }
1241
1242    #[test]
1243    fn bitfield_bitwise() {
1244        #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
1245        struct Simple;
1246        // Dumb layout
1247        impl Layout for Simple {
1248            type Layout = core::iter::Empty<()>;
1249            fn layout() -> Self::Layout { std::iter::empty() }
1250        }
1251
1252        let bitand_result: BitField<Simple, u8> = BitField::new(42) & BitField::new(0b1111);
1253        assert_eq!(BitField::<Simple, u8>::new(0b1010), bitand_result, "BitAnd");
1254
1255        let mut bitand_assign_result: BitField<Simple, u8> = BitField::new(42);
1256        bitand_assign_result &= BitField::new(0b1111);
1257        assert_eq!(BitField::<Simple, u8>::new(0b1010), bitand_assign_result, "BitAndAssign");
1258
1259        let bitor_result: BitField<Simple, u8> = BitField::new(42) | BitField::new(0b1111);
1260        assert_eq!(BitField::<Simple, u8>::new(0b101111), bitor_result, "BitOr");
1261
1262        let mut bitor_assign_result: BitField<Simple, u8> = BitField::new(42);
1263        bitor_assign_result |= BitField::new(0b1111);
1264        assert_eq!(BitField::<Simple, u8>::new(0b101111), bitor_assign_result, "BitOrAssign");
1265
1266        let bitxor_result: BitField<Simple, u8> = BitField::new(42) ^ BitField::new(0b1111);
1267        assert_eq!(BitField::<Simple, u8>::new(0b100101), bitxor_result, "BitXor");
1268
1269        let mut bitxor_assign_result: BitField<Simple, u8> = BitField::new(42);
1270        bitxor_assign_result ^= BitField::new(0b1111);
1271        assert_eq!(BitField::<Simple, u8>::new(0b100101), bitxor_assign_result, "BitXorAssign");
1272    }
1273}