Skip to content

Commit

Permalink
fix(bitfield): don't have fmt::alt control struct formatting (#292)
Browse files Browse the repository at this point in the history
For `fmt::UpperHex`, `fmt::LowerHex`, and `fmt::Binary`, the "alt mode"
format controls whether or not a leading `0x` or `0b` prefix is emitted.
However, for the implementations of those traits on generated bitfield
types, it will also effect the formatting behavior of `fmt::DebugTuple`
(enabling multi-line format), as the generated format impls currently
use `DebugTuple`.

This commit removes the use of `DebugTuple`, and changes the types to
just generate their own tuple-struct-like formatting. This way, we won't
output a multiline format for a bitfield type just because the user
wanted a leading `0b` prefix or `0x` prefix.
  • Loading branch information
hawkw committed Aug 8, 2022
1 parent b6138c8 commit 03055f0
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 14 deletions.
49 changes: 39 additions & 10 deletions bitfield/src/bitfield.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
/// # Generated Implementations
///
/// The `bitfield!` macro generates a type with the following functions, where
/// `T` is the integer type that represents the bitfield (one of `u8`, `u16`,
/// `u32`, `u64`, or `usize`):
/// `{int}` is the integer type that represents the bitfield (one of `u8`,
/// `u16`,`u32`, `u64`, or `usize`):
///
/// | Function | Description |
/// |:--|:--|
/// | `fn new() -> Self` | Returns a new instance of the bitfield type with all bits zeroed. |
/// | `fn from_bits(bits: T) -> Self` | Converts a `T` into an instance of the bitfield type. |
/// | `const fn new() -> Self` | Returns a new instance of the bitfield type with all bits zeroed. |
/// | `const fn from_bits(bits: {int}) -> Self` | Converts an `{int}` into an instance of the bitfield type. |
/// | `const fn bits(self) -> {int}` | Returns this bitfield's bits as a raw integer value. |
/// | `fn with<U>(self, packer: Self::Packer<U>, value: U) -> Self` | Given one of this type's generated packing specs for a `U`-typed value, and a `U`-typed value, returns a new instance of `Self` with the bit representation of `value` packed into the range represented by `packer`. |
/// | `fn set<U>(&mut self, packer: Self::Packer<U>, value: U) -> &mut Self` | Similar to `with`, except `self` is mutated in place, rather than returning a new instance of `Self`. |
/// | `fn get<U>(&self, packer: Self::Packer<U>) -> U` | Given one of this type's generated packing specs for a `U`-typed value, unpacks the bit range represented by that value as a `U` and returns it. This method panics if the requested bit range does not contain a valid bit pattern for a `U`-typed value, as determined by `U`'s implementation of the [`FromBits`] trait. |
Expand Down Expand Up @@ -47,6 +48,8 @@
/// | [`fmt::Display`] | Pretty-prints the bitfield in a very nice-looking multi-line format which I'm rather proud of. See [here](#example-display-output) for examples of this format. |
/// | [`Copy`] | Behaves identically as the [`Copy`] implementation for the underlying integer type. |
/// | [`Clone`] | Behaves identically as the [`Clone`] implementation for the underlying integer type. |
/// | [`From`]`<{int}> for Self` | Converts a raw integer value into an instance of the bitfield type. This is equivalent to calling the bitfield type's `from_bits` function. |
/// | [`From`]`<Self> for {int}` | Converts an instance of the bitfield type into a raw integer value. This is equivalent to calling the bitfield type's `bits` method. |
///
/// Additional traits may be derived for the bitfield type, such as
/// [`PartialEq`], [`Eq`], and [`Default`]. These traits are not automatically
Expand Down Expand Up @@ -311,15 +314,25 @@ macro_rules! bitfield {
),+];

/// Constructs a new instance of `Self` from the provided raw bits.
#[inline]
#[must_use]
$vis const fn from_bits(bits: $T) -> Self {
Self(bits)
}

/// Constructs a new instance of `Self` with all bits set to 0.
#[inline]
#[must_use]
$vis const fn new() -> Self {
Self(0)
}

/// Returns the raw bit representatiion of `self` as an integer.
#[inline]
$vis const fn bits(self) -> $T {
self.0
}

/// Packs the bit representation of `value` into `self` at the bit
/// range designated by `field`, returning a new bitfield.
$vis fn with<T>(self, field: $crate::bitfield! { @t $T, T, Self }, value: T) -> Self
Expand Down Expand Up @@ -485,9 +498,9 @@ macro_rules! bitfield {
impl core::fmt::Binary for $Name {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if f.alternate() {
f.debug_tuple(stringify!($Name)).field(&format_args!("{:#b}", self.0)).finish()
write!(f, concat!(stringify!($Name), "({:#b})"), self.0)
} else {
f.debug_tuple(stringify!($Name)).field(&format_args!("{:b}", self.0)).finish()
write!(f, concat!(stringify!($Name), "({:b})"), self.0)
}
}
}
Expand All @@ -496,9 +509,9 @@ macro_rules! bitfield {
impl core::fmt::UpperHex for $Name {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if f.alternate() {
f.debug_tuple(stringify!($Name)).field(&format_args!("{:#X}", self.0)).finish()
write!(f, concat!(stringify!($Name), "({:#X})"), self.0)
} else {
f.debug_tuple(stringify!($Name)).field(&format_args!("{:X}", self.0)).finish()
write!(f, concat!(stringify!($Name), "({:X})"), self.0)
}
}
}
Expand All @@ -507,12 +520,28 @@ macro_rules! bitfield {
impl core::fmt::LowerHex for $Name {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if f.alternate() {
f.debug_tuple(stringify!($Name)).field(&format_args!("{:#x}", self.0)).finish()
write!(f, concat!(stringify!($Name), "({:#x})"), self.0)
} else {
f.debug_tuple(stringify!($Name)).field(&format_args!("{:x}", self.0)).finish()
write!(f, concat!(stringify!($Name), "({:x})"), self.0)
}
}
}

#[automatically_derived]
impl From<$T> for $Name {
#[inline]
fn from(val: $T) -> Self {
Self::from_bits(val)
}
}

#[automatically_derived]
impl From<$Name> for $T {
#[inline]
fn from($Name(bits): $Name) -> Self {
bits
}
}
};
(@field<$T:ident>, prev: $Prev:ident:
$(#[$meta:meta])*
Expand Down
4 changes: 0 additions & 4 deletions hal-x86_64/src/segment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,6 @@ impl Selector {
Self::INDEX.pack_into(index, &mut self.0);
self
}

pub fn bits(&self) -> u16 {
self.0
}
}

#[cfg(test)]
Expand Down

0 comments on commit 03055f0

Please sign in to comment.