From c4c13dc1771e8645ad948b4b346b22e876c2a7a6 Mon Sep 17 00:00:00 2001 From: KodrAus Date: Thu, 16 Mar 2023 10:15:11 +1000 Subject: [PATCH 1/2] add repro for multi-bit flags --- src/lib.rs | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 92e2d451..9ad2e47e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1154,17 +1154,39 @@ mod tests { #[test] fn test_display_from_str_roundtrip() { - fn format_parse_case(flags: FmtFlags) { + fn format_parse_case(flags: T) where ::Err: fmt::Display { assert_eq!(flags, { - match flags.to_string().parse::() { + match flags.to_string().parse::() { Ok(flags) => flags, Err(e) => panic!("failed to parse `{}`: {}", flags, e), } }); } - fn parse_case(expected: FmtFlags, flags: &str) { - assert_eq!(expected, flags.parse::().unwrap()); + fn parse_case(expected: T, flags: &str) where ::Err: fmt::Display + fmt::Debug { + assert_eq!(expected, flags.parse::().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 { + Ok(MultiBitFmtFlags(s.parse()?)) + } } format_parse_case(FmtFlags::empty()); @@ -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"); From 5ba27cfd4be3ae756b6770dab7e75b9d9f43cbc6 Mon Sep 17 00:00:00 2001 From: KodrAus Date: Thu, 16 Mar 2023 11:37:05 +1000 Subject: [PATCH 2/2] use the iterator state as the source of extra bits --- src/internal.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/internal.rs b/src/internal.rs index ff75be37..fd09a1a3 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -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(" | ")?; } @@ -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(" | ")?;