1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
macro_rules! bitflags_ext { ( struct $flags:ident : $ty:ty { $($( $name:ident = $value:expr ),+ $(,)?)? } ) => { bitflags_ext! { @impl () $flags : $ty [$($($name = $value),+)?] } }; ( pub $(($($vis:tt)+))? struct $flags:ident : $ty:ty { $($( $name:ident = $value:expr ),+ $(,)?)? } ) => { bitflags_ext! { @impl (pub $(($($vis)+))?) $flags : $ty [$($($name = $value),+)?] } }; ( @impl ($($vis:tt)*) $flags:ident : $ty:ty [$($name:ident = $value:expr),*] ) => { bitflags::bitflags! { #[derive(Default)] $($vis)* struct $flags: $ty { $(const $name = $value;)* } } impl ::core::fmt::Display for $flags { fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { let mut start = true; $( if self.contains($flags::$name) { if start { #[allow(unused_assignments)] start = false; } else { write!(f, " ")?; } write!(f, stringify!($name))?; } )* Ok(()) } } impl ::core::str::FromStr for $flags { type Err = (); fn from_str(s: &str) -> Result<$flags, Self::Err> { let mut flags = $flags::empty(); for f in s.split(char::is_whitespace) { match f { "" => { }, $( stringify!($name) => flags |= $flags::$name, )* _ => return Err(()) } } Ok(flags) } } } }