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}