Skip to content

Commit

Permalink
Merge pull request #235 from konsumlamm/multiple-bitflags
Browse files Browse the repository at this point in the history
Allow multiple bitflags structs in one macro invocation
  • Loading branch information
KodrAus committed May 11, 2021
2 parents c2ba431 + 380d3c0 commit bd24f9d
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 40 deletions.
4 changes: 2 additions & 2 deletions build.rs
Expand Up @@ -2,7 +2,7 @@ use std::env;
use std::process::Command;
use std::str::{self, FromStr};

fn main(){
fn main() {
let minor = match rustc_minor_version() {
Some(minor) => minor,
None => return,
Expand Down Expand Up @@ -41,4 +41,4 @@ fn rustc_minor_version() -> Option<u32> {
};

u32::from_str(next).ok()
}
}
80 changes: 52 additions & 28 deletions src/lib.rs
Expand Up @@ -11,7 +11,7 @@
//! A typesafe bitmask flag generator useful for sets of C-style bitmask flags.
//! It can be used for creating typesafe wrappers around C APIs.
//!
//! The `bitflags!` macro generates a `struct` that manages a set of flags. The
//! The `bitflags!` macro generates `struct`s that manage a set of flags. The
//! flags should only be defined for integer types, otherwise unexpected type
//! errors may occur at compile time.
//!
Expand Down Expand Up @@ -84,9 +84,9 @@
//!
//! # Visibility
//!
//! The generated struct and its associated flag constants are not exported
//! The generated structs and their associated flag constants are not exported
//! out of the current module by default. A definition can be exported out of
//! the current module by adding `pub` before `flags`:
//! the current module by adding `pub` before `struct`:
//!
//! ```
//! #[macro_use]
Expand All @@ -97,8 +97,7 @@
//! pub struct Flags1: u32 {
//! const A = 0b00000001;
//! }
//! }
//! bitflags! {
//!
//! # pub
//! struct Flags2: u32 {
//! const B = 0b00000010;
Expand All @@ -114,26 +113,26 @@
//!
//! # Attributes
//!
//! Attributes can be attached to the generated `struct` by placing them
//! before the `flags` keyword.
//! Attributes can be attached to the generated `struct`s by placing them
//! before the `struct` keyword.
//!
//! # Trait implementations
//!
//! The `Copy`, `Clone`, `PartialEq`, `Eq`, `PartialOrd`, `Ord` and `Hash`
//! traits automatically derived for the `struct` using the `derive` attribute.
//! traits are automatically derived for the `struct`s using the `derive` attribute.
//! Additional traits can be derived by providing an explicit `derive`
//! attribute on `flags`.
//! attribute on `struct`.
//!
//! The `Extend` and `FromIterator` traits are implemented for the `struct`,
//! The `Extend` and `FromIterator` traits are implemented for the `struct`s,
//! too: `Extend` adds the union of the instances of the `struct` iterated over,
//! while `FromIterator` calculates the union.
//!
//! The `Binary`, `Debug`, `LowerHex`, `Octal` and `UpperHex` trait is also
//! The `Binary`, `Debug`, `LowerHex`, `Octal` and `UpperHex` traits are also
//! implemented by displaying the bits value of the internal struct.
//!
//! ## Operators
//!
//! The following operator traits are implemented for the generated `struct`:
//! The following operator traits are implemented for the generated `struct`s:
//!
//! - `BitOr` and `BitOrAssign`: union
//! - `BitAnd` and `BitAndAssign`: intersection
Expand All @@ -143,7 +142,7 @@
//!
//! # Methods
//!
//! The following methods are defined for the generated `struct`:
//! The following methods are defined for the generated `struct`s:
//!
//! - `empty`: an empty set of flags
//! - `all`: the set of all defined flags
Expand All @@ -168,7 +167,7 @@
//!
//! ## Default
//!
//! The `Default` trait is not automatically implemented for the generated struct.
//! The `Default` trait is not automatically implemented for the generated structs.
//!
//! If your default value is equal to `0` (which is the same value as calling `empty()`
//! on the generated struct), you can simply derive `Default`:
Expand Down Expand Up @@ -262,7 +261,7 @@ extern crate std;
#[doc(hidden)]
pub extern crate core as _core;

/// The macro used to generate the flag structure.
/// The macro used to generate the flag structures.
///
/// See the [crate level docs](../bitflags/index.html) for complete documentation.
///
Expand Down Expand Up @@ -339,6 +338,7 @@ macro_rules! bitflags {
const $Flag:ident = $value:expr;
)+
}
$($t:tt)*
) => {
__bitflags! {
$(#[$outer])*
Expand All @@ -349,6 +349,10 @@ macro_rules! bitflags {
)+
}
}

bitflags! {
$($t)*
}
};
(
$(#[$outer:meta])*
Expand All @@ -358,6 +362,7 @@ macro_rules! bitflags {
const $Flag:ident = $value:expr;
)+
}
$($t:tt)*
) => {
__bitflags! {
$(#[$outer])*
Expand All @@ -368,6 +373,10 @@ macro_rules! bitflags {
)+
}
}

bitflags! {
$($t)*
}
};
(
$(#[$outer:meta])*
Expand All @@ -377,6 +386,7 @@ macro_rules! bitflags {
const $Flag:ident = $value:expr;
)+
}
$($t:tt)*
) => {
__bitflags! {
$(#[$outer])*
Expand All @@ -387,7 +397,12 @@ macro_rules! bitflags {
)+
}
}

bitflags! {
$($t)*
}
};
() => {};
}

#[macro_export(local_inner_macros)]
Expand Down Expand Up @@ -958,9 +973,7 @@ mod tests {
#[doc = "<strcat> wait what?"]
const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
}
}

bitflags! {
struct _CfgFlags: u32 {
#[cfg(unix)]
const _CFG_A = 0b01;
Expand All @@ -969,15 +982,11 @@ mod tests {
#[cfg(unix)]
const _CFG_C = Self::_CFG_A.bits | 0b10;
}
}

bitflags! {
struct AnotherSetOfFlags: i8 {
const ANOTHER_FLAG = -1_i8;
}
}

bitflags! {
struct LongFlags: u32 {
const LONG_A = 0b1111111111111111;
}
Expand Down Expand Up @@ -1028,9 +1037,18 @@ 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));
assert_eq!(unsafe { Flags::from_bits_unchecked(0b1000) }, (extra | Flags::empty()));
assert_eq!(unsafe { Flags::from_bits_unchecked(0b1001) }, (extra | Flags::A));
assert_eq!(
unsafe { Flags::from_bits_unchecked(0b11) },
(Flags::A | Flags::B)
);
assert_eq!(
unsafe { Flags::from_bits_unchecked(0b1000) },
(extra | Flags::empty())
);
assert_eq!(
unsafe { Flags::from_bits_unchecked(0b1001) },
(extra | Flags::A)
);
}

#[test]
Expand Down Expand Up @@ -1177,7 +1195,6 @@ mod tests {
assert_eq!(m1, e1);
}


#[cfg(bitflags_const_fn)]
#[test]
fn test_const_fn() {
Expand Down Expand Up @@ -1276,7 +1293,10 @@ 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!("{:?}", Flags::ABC | extra),
"A | B | C | ABC | 0xb8"
);
}

#[test]
Expand Down Expand Up @@ -1320,8 +1340,7 @@ mod tests {
pub struct PublicFlags: i8 {
const X = 0;
}
}
bitflags! {

struct PrivateFlags: i8 {
const Y = 0;
}
Expand Down Expand Up @@ -1436,4 +1455,9 @@ mod tests {
assert_eq!(format!("{:?}", Flags::empty()), "NONE");
assert_eq!(format!("{:?}", Flags::SOME), "SOME");
}

#[test]
fn test_empty_bitflags() {
bitflags! {}
}
}
3 changes: 1 addition & 2 deletions test_suite/tests/compile-fail/private_flags.rs
Expand Up @@ -6,8 +6,7 @@ mod example {
pub struct Flags1: u32 {
const FLAG_A = 0b00000001;
}
}
bitflags! {

struct Flags2: u32 {
const FLAG_B = 0b00000010;
}
Expand Down
18 changes: 10 additions & 8 deletions test_suite/tests/compile-fail/private_flags.stderr
@@ -1,16 +1,18 @@
error[E0603]: struct `Flags2` is private
--> $DIR/private_flags.rs:19:26
--> $DIR/private_flags.rs:18:26
|
19 | let flag2 = example::Flags2::FLAG_B;
18 | let flag2 = example::Flags2::FLAG_B;
| ^^^^^^ private struct
|
note: the struct `Flags2` is defined here
--> $DIR/private_flags.rs:10:5
--> $DIR/private_flags.rs:5:5
|
10 | / bitflags! {
11 | | struct Flags2: u32 {
12 | | const FLAG_B = 0b00000010;
13 | | }
14 | | }
5 | / bitflags! {
6 | | pub struct Flags1: u32 {
7 | | const FLAG_A = 0b00000001;
8 | | }
... |
12 | | }
13 | | }
| |_____^
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

0 comments on commit bd24f9d

Please sign in to comment.