Skip to content

Commit

Permalink
Merge pull request #225 from thiagoarrais/empty
Browse files Browse the repository at this point in the history
Allows empty flag definition
  • Loading branch information
KodrAus committed May 16, 2021
2 parents 789e63c + 6e93266 commit ec76dd2
Showing 1 changed file with 97 additions and 29 deletions.
126 changes: 97 additions & 29 deletions src/lib.rs
Expand Up @@ -360,7 +360,7 @@ macro_rules! bitflags {
$(
$(#[$inner:ident $($args:tt)*])*
const $Flag:ident = $value:expr;
)+
)*
}
$($t:tt)*
) => {
Expand All @@ -370,7 +370,7 @@ macro_rules! bitflags {
$(
$(#[$inner $($args)*])*
$Flag = $value;
)+
)*
}
}

Expand Down Expand Up @@ -414,7 +414,7 @@ macro_rules! __bitflags {
$(
$(#[$inner:ident $($args:tt)*])*
$Flag:ident = $value:expr;
)+
)*
}
) => {
$(#[$outer])*
Expand All @@ -428,7 +428,7 @@ macro_rules! __bitflags {
$(
$(#[$inner $($args)*])*
$Flag = $value;
)+
)*
}
}
};
Expand Down Expand Up @@ -490,14 +490,63 @@ macro_rules! __fn_bitflags {

#[macro_export(local_inner_macros)]
#[doc(hidden)]
macro_rules! __impl_bitflags {
macro_rules! __all_bitflags {
(
$BitFlags:ident: $T:ty {
$(
$(#[$attr:ident $($args:tt)*])*
$Flag:ident = $value:expr;
)+
}
) => {
__fn_bitflags! {
/// Returns the set containing all flags.
#[inline]
pub const fn all() -> $BitFlags {
// See `Debug::fmt` for why this approach is taken.
#[allow(non_snake_case)]
trait __BitFlags {
$(
const $Flag: $T = 0;
)+
}
impl __BitFlags for $BitFlags {
$(
__impl_bitflags! {
#[allow(deprecated)]
$(? #[$attr $($args)*])*
const $Flag: $T = Self::$Flag.bits;
}
)+
}
$BitFlags { bits: $(<$BitFlags as __BitFlags>::$Flag)|+ }
}
}
};
(
$BitFlags:ident: $T:ty {
}
) => {
__fn_bitflags! {
/// Returns the set containing all flags.
#[inline]
pub const fn all() -> $BitFlags {
$BitFlags { bits: 0 }
}
}
};
}

#[macro_export(local_inner_macros)]
#[doc(hidden)]
macro_rules! __impl_bitflags {
(
$BitFlags:ident: $T:ty {
$(
$(#[$attr:ident $($args:tt)*])*
$Flag:ident = $value:expr;
)*
}
) => {
impl $crate::_core::fmt::Debug for $BitFlags {
fn fmt(&self, f: &mut $crate::_core::fmt::Formatter) -> $crate::_core::fmt::Result {
Expand All @@ -514,7 +563,7 @@ macro_rules! __impl_bitflags {
$(
#[inline]
fn $Flag(&self) -> bool { false }
)+
)*
}

// Conditionally override the check for just those flags that
Expand All @@ -533,7 +582,7 @@ macro_rules! __impl_bitflags {
}
}
}
)+
)*
}

let mut first = true;
Expand All @@ -545,7 +594,7 @@ macro_rules! __impl_bitflags {
first = false;
f.write_str(__bitflags_stringify!($Flag))?;
}
)+
)*
let extra_bits = self.bits & !$BitFlags::all().bits();
if extra_bits != 0 {
if !first {
Expand Down Expand Up @@ -587,7 +636,7 @@ macro_rules! __impl_bitflags {
$(
$(#[$attr $($args)*])*
pub const $Flag: $BitFlags = $BitFlags { bits: $value };
)+
)*

__fn_bitflags! {
/// Returns an empty set of flags.
Expand All @@ -597,29 +646,14 @@ macro_rules! __impl_bitflags {
}
}

__fn_bitflags! {
/// Returns the set containing all flags.
#[inline]
pub const fn all() -> $BitFlags {
// See `Debug::fmt` for why this approach is taken.
#[allow(non_snake_case)]
trait __BitFlags {
$(
const $Flag: $T = 0;
)+
}
impl __BitFlags for $BitFlags {
__all_bitflags! {
$BitFlags: $T {
$(
__impl_bitflags! {
#[allow(deprecated)]
$(? #[$attr $($args)*])*
const $Flag: $T = Self::$Flag.bits;
}
)+
$(#[$attr $($args)*])*
$Flag = $value;
)*
}
$BitFlags { bits: $(<$BitFlags as __BitFlags>::$Flag)|+ }
}
}

__fn_bitflags! {
/// Returns the raw value of the flags currently stored.
Expand Down Expand Up @@ -992,6 +1026,11 @@ mod tests {
}
}

bitflags! {
struct EmptyFlags: u32 {
}
}

#[test]
fn test_bits() {
assert_eq!(Flags::empty().bits(), 0b00000000);
Expand All @@ -1000,6 +1039,8 @@ mod tests {

assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00);
assert_eq!(AnotherSetOfFlags::ANOTHER_FLAG.bits(), !0_i8);

assert_eq!(EmptyFlags::empty().bits(), 0b00000000);
}

#[test]
Expand All @@ -1014,6 +1055,9 @@ mod tests {
AnotherSetOfFlags::from_bits(!0_i8),
Some(AnotherSetOfFlags::ANOTHER_FLAG)
);

assert_eq!(EmptyFlags::from_bits(0), Some(EmptyFlags::empty()));
assert_eq!(EmptyFlags::from_bits(0b1), None);
}

#[test]
Expand All @@ -1029,6 +1073,9 @@ mod tests {
AnotherSetOfFlags::from_bits_truncate(0_i8),
AnotherSetOfFlags::empty()
);

assert_eq!(EmptyFlags::from_bits_truncate(0), EmptyFlags::empty());
assert_eq!(EmptyFlags::from_bits_truncate(0b1), EmptyFlags::empty());
}

#[test]
Expand All @@ -1037,6 +1084,7 @@ mod tests {
assert_eq!(unsafe { Flags::from_bits_unchecked(0) }, Flags::empty());
assert_eq!(unsafe { Flags::from_bits_unchecked(0b1) }, Flags::A);
assert_eq!(unsafe { Flags::from_bits_unchecked(0b10) }, Flags::B);

assert_eq!(
unsafe { Flags::from_bits_unchecked(0b11) },
(Flags::A | Flags::B)
Expand All @@ -1049,6 +1097,12 @@ mod tests {
unsafe { Flags::from_bits_unchecked(0b1001) },
(extra | Flags::A)
);

let extra = unsafe { EmptyFlags::from_bits_unchecked(0b1000) };
assert_eq!(
unsafe { EmptyFlags::from_bits_unchecked(0b1000) },
(extra | EmptyFlags::empty())
);
}

#[test]
Expand All @@ -1058,6 +1112,9 @@ mod tests {
assert!(!Flags::ABC.is_empty());

assert!(!AnotherSetOfFlags::ANOTHER_FLAG.is_empty());

assert!(EmptyFlags::empty().is_empty());
assert!(EmptyFlags::all().is_empty());
}

#[test]
Expand All @@ -1067,6 +1124,9 @@ mod tests {
assert!(Flags::ABC.is_all());

assert!(AnotherSetOfFlags::ANOTHER_FLAG.is_all());

assert!(EmptyFlags::all().is_all());
assert!(EmptyFlags::empty().is_all());
}

#[test]
Expand Down Expand Up @@ -1108,6 +1168,8 @@ mod tests {
assert!(Flags::ABC.contains(e2));

assert!(AnotherSetOfFlags::ANOTHER_FLAG.contains(AnotherSetOfFlags::ANOTHER_FLAG));

assert!(EmptyFlags::empty().contains(EmptyFlags::empty()));
}

#[test]
Expand Down Expand Up @@ -1293,10 +1355,16 @@ mod tests {
let extra = unsafe { Flags::from_bits_unchecked(0xb8) };
assert_eq!(format!("{:?}", extra), "0xb8");
assert_eq!(format!("{:?}", Flags::A | extra), "A | 0xb8");

assert_eq!(
format!("{:?}", Flags::ABC | extra),
"A | B | C | ABC | 0xb8"
);

assert_eq!(
format!("{:?}", EmptyFlags::empty()),
"(empty)"
);
}

#[test]
Expand Down

0 comments on commit ec76dd2

Please sign in to comment.