Struct BitField

Source
pub struct BitField<M, T> {
    pub value: T,
    /* private fields */
}
Expand description

Accessory struct for convinient type construction

This structure holds value of created bitfield type and may be used for types that doesn’t has own value field: enums and unit-like structs.

§Enum wrapper

Using enumeration as bitfield type has the following advantage - you can bind bit (flag) to one of enum variants.

 
// Declare new bitfield type
enum EightFlags {
    One,
    Two,
    Three,
    Four,
    OemReserved(u8), // Reserved field referenced to multiple bits
    FutureReserved(u8), // Reserved field referenced to multiple bits
}
// Implement Dispaly trait for basic and alternative views
impl fmt::Display for EightFlags {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match (self, f.alternate()) {
            // Basic view
            (Self::One,   false) => write!(f, "one"),
            (Self::Two,   false) => write!(f, "two"),
            (Self::Three, false) => write!(f, "three"),
            (Self::Four,  false) => write!(f, "four"),
            // Alternative view
            (Self::One,   true)  => write!(f, "ONE"),
            (Self::Two,   true)  => write!(f, "TWO"),
            (Self::Three, true)  => write!(f, "THREE"),
            (Self::Four,  true)  => write!(f, "FOUR"),
            // Reserved fields
            (Self::OemReserved(v), _) => write!(f, "OEM reserved (#{})", v),
            (Self::FutureReserved(v), _) => write!(f, "Reserved for future usage (#{})", v),
        }
    }
}
// Implement constant bit layout for this type
impl EightFlags {
    const LAYOUT: [Self; 8] = [
        Self::One,
        Self::Two,
        Self::Three,
        Self::Four,
        Self::OemReserved(4),
        Self::OemReserved(5),
        Self::FutureReserved(6),
        Self::FutureReserved(7),
    ];
}
// Implement Layout for enum created early
impl Layout for EightFlags {
    type Layout = std::slice::Iter<'static, EightFlags>;
    fn layout() -> Self::Layout { EightFlags::LAYOUT.iter() }
}
 
// Now we can use wrapped bitfield enum
let bf: BitField<EightFlags, u8> = BitField::new(0b01100101);
 
// Get only setted flags
let result = bf.flags()
    .filter_map(|f| {
        if f.is_set {
            match f.value {
                EightFlags::OemReserved(v) =>
                    Some(format!("Reserved flag #{}", v)),
                EightFlags::FutureReserved(_) =>
                    Some(format!("{}", f.value)),
                v @ _ =>
                    Some(format!("Name: {}, Description: {:#}", v, v)),
            }
        } else {
            None
        }
    })
    .collect::<Vec<_>>();
 
let sample = vec![
    "Name: one, Description: ONE",
    "Name: three, Description: THREE",
    "Reserved flag #5",
    "Reserved for future usage (#6)",
];
assert_eq!(sample, result, "Wrapped enum");

§Unit-like struct wrapper

We can use bitfield type defined as unit-like struct in the same way as for enum

 
// Unit-like struct without value
struct Status;
// Bind flags layout to this struct
impl Status {
    const LAYOUT: [&'static str; 8] = [
        "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
    ];
}
// Implement layout trait
impl Layout for Status {
    type Layout = core::slice::Iter<'static, &'static str>;
    fn layout() -> Self::Layout { Status::LAYOUT.iter() }
}
 
let bf: BitField<Status, u8> = BitField::new(42);
// Get formatted strings from flags iteartor
let result = bf.flags()
    .map(|f| format!("{:#}", f.value))
    .collect::<Vec<_>>();
let sample = vec!["s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7"];
assert_eq!(sample, result, "Simple unit-like struct");
 

§Unit-like struct with associated constants

Also we can use unit-like struct with associated constant flags. This will gave us feauture to has marked bits. This realisation somewhere in beetween enum and simple unit-like struct.

 
 
// Unit-like struct without value
struct Status;
// Implement layout. You can leave comments on every item. For example, you can use bit id as
// Status::ONE.
impl Status {
    const ONE: &'static str = "One";
    const TWO: &'static str = "Two";
    const THREE: &'static str = "Three";
    const FOUR: &'static str = "Four";
    const RESERVED: &'static str = "Reserved";
    const UNKNOWN: &'static str = "Unknown";
 
    const LAYOUT: [&'static str; 8] = [
        Self::ONE,
        Self::TWO,
        Self::THREE,
        Self::FOUR,
        Self::RESERVED,
        Self::RESERVED,
        Self::RESERVED,
        Self::UNKNOWN,
    ];
}
// Implement layout trait
impl Layout for Status {
    type Layout = core::slice::Iter<'static, &'static str>;
    fn layout() -> Self::Layout { Status::LAYOUT.iter() }
}
 
let bf: BitField<Status, u8> = BitField::new(0b00001000);
let result = bf.flags()
    .find(|f| f.is_set)
    .map(|f| f.value)
    .unwrap();
assert_eq!(Status::FOUR, *result, "Enumeration");

Fields§

§value: T

Implementations§

Source§

impl<M, T> BitField<M, T>

Source

pub fn new(value: T) -> Self

Trait Implementations§

Source§

impl<M, T> BitAnd for BitField<M, T>
where M: Layout, T: Copy + IntoBits + FromBits + BitAnd<Output = T>,

Source§

type Output = BitField<M, T>

The resulting type after applying the & operator.
Source§

fn bitand(self, rhs: Self) -> Self::Output

Performs the & operation. Read more
Source§

impl<M, T> BitAndAssign for BitField<M, T>
where M: Layout, T: Copy + IntoBits + FromBits + BitAnd<Output = T>,

Source§

fn bitand_assign(&mut self, rhs: Self)

Performs the &= operation. Read more
Source§

impl<M: Layout, T: Copy + IntoBits + FromBits> BitFieldLayout for BitField<M, T>

Source§

type Value = T

Source§

fn get(&self) -> Self::Value

Returns a copy of the contained value.
Source§

fn set(&mut self, new: Self::Value)

Sets the contained value.
Source§

fn replace(&mut self, new: Self::Value) -> Self::Value

Replaces the contained value with val, and returns the old contained value. Read more
Source§

fn swap(&mut self, other: &mut Self)

Swaps the values of two bitfields. Read more
Source§

fn update<F>(&mut self, f: F) -> Self::Value
where F: FnOnce(Self::Value) -> Self::Value,

Updates the contained value using a function and returns the new value. Read more
Source§

fn insert_flag(&mut self, position: usize, b: bool) -> bool

Set the specified bit (flag) in-place. Returns current state Read more
Source§

fn toggle_flag(&mut self, position: usize)

The specified bit (flag) will be inverted Read more
Source§

fn bits(&self) -> Bits<<Self::Value as IntoBits>::Bytes>

Return iterator through bitfield value bits. Every bit represents as bool value. Read more
Source§

fn flags(&self) -> Flags<Self::Layout, Bits<<Self::Value as IntoBits>::Bytes>>

Return iterator through bitfield value flags. Every flag contains bit state (set or unset) and item (record) value - string in simple case. Read more
Source§

fn diff( &self, other: Self, ) -> Diff<Self::Layout, Bits<<Self::Value as IntoBits>::Bytes>>
where Self: Sized,

Helps to find difference between two bitfield values. Read more
Source§

fn find_state<P>(&self, predicate: P) -> Option<bool>
where P: Fn(<<Self as Layout>::Layout as Iterator>::Item) -> bool,

Find specific flag state. None if not find Read more
Source§

impl<M, T> BitOr for BitField<M, T>
where M: Layout, T: Copy + IntoBits + FromBits + BitOr<Output = T>,

Source§

type Output = BitField<M, T>

The resulting type after applying the | operator.
Source§

fn bitor(self, rhs: Self) -> Self::Output

Performs the | operation. Read more
Source§

impl<M, T> BitOrAssign for BitField<M, T>
where M: Layout, T: Copy + IntoBits + FromBits + BitOr<Output = T>,

Source§

fn bitor_assign(&mut self, rhs: Self)

Performs the |= operation. Read more
Source§

impl<M, T> BitXor for BitField<M, T>
where M: Layout, T: Copy + IntoBits + FromBits + BitXor<Output = T>,

Source§

type Output = BitField<M, T>

The resulting type after applying the ^ operator.
Source§

fn bitxor(self, rhs: Self) -> Self::Output

Performs the ^ operation. Read more
Source§

impl<M, T> BitXorAssign for BitField<M, T>
where M: Layout, T: Copy + IntoBits + FromBits + BitXor<Output = T>,

Source§

fn bitxor_assign(&mut self, rhs: Self)

Performs the ^= operation. Read more
Source§

impl<M: Clone, T: Clone> Clone for BitField<M, T>

Source§

fn clone(&self) -> BitField<M, T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<M: Debug, T: Debug> Debug for BitField<M, T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<M: Hash, T: Hash> Hash for BitField<M, T>

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<M: Layout, T> Layout for BitField<M, T>

Source§

type Layout = <M as Layout>::Layout

Layout iterator. Typically constant array or slice
Source§

fn layout() -> Self::Layout

Return iterator through layout items. Actual layout may be implemented inside this function or be a associated constant of bitfield type
Source§

impl<M: Ord, T: Ord> Ord for BitField<M, T>

Source§

fn cmp(&self, other: &BitField<M, T>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

impl<M: PartialEq, T: PartialEq> PartialEq for BitField<M, T>

Source§

fn eq(&self, other: &BitField<M, T>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<M: PartialOrd, T: PartialOrd> PartialOrd for BitField<M, T>

Source§

fn partial_cmp(&self, other: &BitField<M, T>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl<M: Eq, T: Eq> Eq for BitField<M, T>

Source§

impl<M, T> StructuralPartialEq for BitField<M, T>

Auto Trait Implementations§

§

impl<M, T> Freeze for BitField<M, T>
where T: Freeze,

§

impl<M, T> RefUnwindSafe for BitField<M, T>

§

impl<M, T> Send for BitField<M, T>
where T: Send, M: Send,

§

impl<M, T> Sync for BitField<M, T>
where T: Sync, M: Sync,

§

impl<M, T> Unpin for BitField<M, T>
where T: Unpin, M: Unpin,

§

impl<M, T> UnwindSafe for BitField<M, T>
where T: UnwindSafe, M: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.