Skip to content

Commit af44dcc

Browse files
authored
Merge pull request #316 from KodrAus/fix/multi-bit-flag-fmt
Fix formatting of multi-bit flags with partial overlap
2 parents ad02711 + 5ba27cf commit af44dcc

2 files changed

Lines changed: 30 additions & 7 deletions

File tree

src/internal.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ macro_rules! __impl_internal_bitflags {
8989

9090
// Iterate over the valid flags
9191
let mut first = true;
92-
for (name, _) in self.iter_names() {
92+
let mut iter = self.iter_names();
93+
for (name, _) in &mut iter {
9394
if !first {
9495
f.write_str(" | ")?;
9596
}
@@ -99,8 +100,7 @@ macro_rules! __impl_internal_bitflags {
99100
}
100101

101102
// Append any extra bits that correspond to flags to the end of the format
102-
let extra_bits = self.bits & !Self::all().bits;
103-
103+
let extra_bits = iter.state.bits();
104104
if extra_bits != <$T as $crate::__private::Bits>::EMPTY {
105105
if !first {
106106
f.write_str(" | ")?;

src/lib.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,17 +1154,39 @@ mod tests {
11541154

11551155
#[test]
11561156
fn test_display_from_str_roundtrip() {
1157-
fn format_parse_case(flags: FmtFlags) {
1157+
fn format_parse_case<T: fmt::Debug + fmt::Display + str::FromStr + PartialEq>(flags: T) where <T as str::FromStr>::Err: fmt::Display {
11581158
assert_eq!(flags, {
1159-
match flags.to_string().parse::<FmtFlags>() {
1159+
match flags.to_string().parse::<T>() {
11601160
Ok(flags) => flags,
11611161
Err(e) => panic!("failed to parse `{}`: {}", flags, e),
11621162
}
11631163
});
11641164
}
11651165

1166-
fn parse_case(expected: FmtFlags, flags: &str) {
1167-
assert_eq!(expected, flags.parse::<FmtFlags>().unwrap());
1166+
fn parse_case<T: fmt::Debug + str::FromStr + PartialEq>(expected: T, flags: &str) where <T as str::FromStr>::Err: fmt::Display + fmt::Debug {
1167+
assert_eq!(expected, flags.parse::<T>().unwrap());
1168+
}
1169+
1170+
bitflags! {
1171+
#[derive(Debug, Eq, PartialEq)]
1172+
pub struct MultiBitFmtFlags: u8 {
1173+
const A = 0b0000_0001u8;
1174+
const B = 0b0001_1110u8;
1175+
}
1176+
}
1177+
1178+
impl fmt::Display for MultiBitFmtFlags {
1179+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1180+
fmt::Display::fmt(&self.0, f)
1181+
}
1182+
}
1183+
1184+
impl str::FromStr for MultiBitFmtFlags {
1185+
type Err = crate::parser::ParseError;
1186+
1187+
fn from_str(s: &str) -> Result<Self, Self::Err> {
1188+
Ok(MultiBitFmtFlags(s.parse()?))
1189+
}
11681190
}
11691191

11701192
format_parse_case(FmtFlags::empty());
@@ -1174,6 +1196,7 @@ mod tests {
11741196
format_parse_case(FmtFlags::물고기_고양이);
11751197
format_parse_case(FmtFlags::from_bits_retain(0xb8));
11761198
format_parse_case(FmtFlags::from_bits_retain(0x20));
1199+
format_parse_case(MultiBitFmtFlags::from_bits_retain(3));
11771200

11781201
parse_case(FmtFlags::empty(), "");
11791202
parse_case(FmtFlags::empty(), " \r\n\t");

0 commit comments

Comments
 (0)