Skip to content

Commit

Permalink
Merge pull request #316 from KodrAus/fix/multi-bit-flag-fmt
Browse files Browse the repository at this point in the history
Fix formatting of multi-bit flags with partial overlap
  • Loading branch information
KodrAus committed Mar 16, 2023
2 parents ad02711 + 5ba27cf commit af44dcc
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 7 deletions.
6 changes: 3 additions & 3 deletions src/internal.rs
Expand Up @@ -89,7 +89,8 @@ macro_rules! __impl_internal_bitflags {

// Iterate over the valid flags
let mut first = true;
for (name, _) in self.iter_names() {
let mut iter = self.iter_names();
for (name, _) in &mut iter {
if !first {
f.write_str(" | ")?;
}
Expand All @@ -99,8 +100,7 @@ macro_rules! __impl_internal_bitflags {
}

// Append any extra bits that correspond to flags to the end of the format
let extra_bits = self.bits & !Self::all().bits;

let extra_bits = iter.state.bits();
if extra_bits != <$T as $crate::__private::Bits>::EMPTY {
if !first {
f.write_str(" | ")?;
Expand Down
31 changes: 27 additions & 4 deletions src/lib.rs
Expand Up @@ -1154,17 +1154,39 @@ mod tests {

#[test]
fn test_display_from_str_roundtrip() {
fn format_parse_case(flags: FmtFlags) {
fn format_parse_case<T: fmt::Debug + fmt::Display + str::FromStr + PartialEq>(flags: T) where <T as str::FromStr>::Err: fmt::Display {
assert_eq!(flags, {
match flags.to_string().parse::<FmtFlags>() {
match flags.to_string().parse::<T>() {
Ok(flags) => flags,
Err(e) => panic!("failed to parse `{}`: {}", flags, e),
}
});
}

fn parse_case(expected: FmtFlags, flags: &str) {
assert_eq!(expected, flags.parse::<FmtFlags>().unwrap());
fn parse_case<T: fmt::Debug + str::FromStr + PartialEq>(expected: T, flags: &str) where <T as str::FromStr>::Err: fmt::Display + fmt::Debug {
assert_eq!(expected, flags.parse::<T>().unwrap());
}

bitflags! {
#[derive(Debug, Eq, PartialEq)]
pub struct MultiBitFmtFlags: u8 {
const A = 0b0000_0001u8;
const B = 0b0001_1110u8;
}
}

impl fmt::Display for MultiBitFmtFlags {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}

impl str::FromStr for MultiBitFmtFlags {
type Err = crate::parser::ParseError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(MultiBitFmtFlags(s.parse()?))
}
}

format_parse_case(FmtFlags::empty());
Expand All @@ -1174,6 +1196,7 @@ mod tests {
format_parse_case(FmtFlags::물고기_고양이);
format_parse_case(FmtFlags::from_bits_retain(0xb8));
format_parse_case(FmtFlags::from_bits_retain(0x20));
format_parse_case(MultiBitFmtFlags::from_bits_retain(3));

parse_case(FmtFlags::empty(), "");
parse_case(FmtFlags::empty(), " \r\n\t");
Expand Down

0 comments on commit af44dcc

Please sign in to comment.