Skip to content

Allow trailing commas in bitflags! macro #16986

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 4, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 123 additions & 104 deletions src/libstd/bitflags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,111 +8,112 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The `bitflags!` macro generates a `struct` that holds a set of C-style
//! bitmask flags. It is useful for creating typesafe wrappers for C APIs.
//!
//! The flags should only be defined for integer types, otherwise unexpected
//! type errors may occur at compile time.
//!
//! # Example
//!
//! ~~~rust
//! bitflags!(
//! flags Flags: u32 {
//! static FlagA = 0x00000001,
//! static FlagB = 0x00000010,
//! static FlagC = 0x00000100,
//! static FlagABC = FlagA.bits
//! | FlagB.bits
//! | FlagC.bits
//! }
//! )
//!
//! fn main() {
//! let e1 = FlagA | FlagC;
//! let e2 = FlagB | FlagC;
//! assert!((e1 | e2) == FlagABC); // union
//! assert!((e1 & e2) == FlagC); // intersection
//! assert!((e1 - e2) == FlagA); // set difference
//! assert!(!e2 == FlagA); // set complement
//! }
//! ~~~
//!
//! The generated `struct`s can also be extended with type and trait implementations:
//!
//! ~~~rust
//! use std::fmt;
//!
//! bitflags!(
//! flags Flags: u32 {
//! static FlagA = 0x00000001,
//! static FlagB = 0x00000010
//! }
//! )
//!
//! impl Flags {
//! pub fn clear(&mut self) {
//! self.bits = 0; // The `bits` field can be accessed from within the
//! // same module where the `bitflags!` macro was invoked.
//! }
//! }
//!
//! impl fmt::Show for Flags {
//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
//! write!(f, "hi!")
//! }
//! }
//!
//! fn main() {
//! let mut flags = FlagA | FlagB;
//! flags.clear();
//! assert!(flags.is_empty());
//! assert_eq!(format!("{}", flags).as_slice(), "hi!");
//! }
//! ~~~
//!
//! # Attributes
//!
//! Attributes can be attached to the generated `struct` by placing them
//! before the `flags` keyword.
//!
//! # Derived traits
//!
//! The `PartialEq` and `Clone` traits are automatically derived for the `struct` using
//! the `deriving` attribute. Additional traits can be derived by providing an
//! explicit `deriving` attribute on `flags`.
//!
//! # Operators
//!
//! The following operator traits are implemented for the generated `struct`:
//!
//! - `BitOr`: union
//! - `BitAnd`: intersection
//! - `Sub`: set difference
//! - `Not`: set complement
//!
//! # Methods
//!
//! The following methods are defined for the generated `struct`:
//!
//! - `empty`: an empty set of flags
//! - `all`: the set of all flags
//! - `bits`: the raw value of the flags currently stored
//! - `is_empty`: `true` if no flags are currently stored
//! - `is_all`: `true` if all flags are currently set
//! - `intersects`: `true` if there are flags common to both `self` and `other`
//! - `contains`: `true` all of the flags in `other` are contained within `self`
//! - `insert`: inserts the specified flags in-place
//! - `remove`: removes the specified flags in-place

#![experimental]
#![macro_escape]

//! A typesafe bitmask flag generator.

/// The `bitflags!` macro generates a `struct` that holds a set of C-style
/// bitmask flags. It is useful for creating typesafe wrappers for C APIs.
///
/// The flags should only be defined for integer types, otherwise unexpected
/// type errors may occur at compile time.
///
/// # Example
///
/// ~~~rust
/// bitflags! {
/// flags Flags: u32 {
/// static FlagA = 0x00000001,
/// static FlagB = 0x00000010,
/// static FlagC = 0x00000100,
/// static FlagABC = FlagA.bits
/// | FlagB.bits
/// | FlagC.bits,
/// }
/// }
///
/// fn main() {
/// let e1 = FlagA | FlagC;
/// let e2 = FlagB | FlagC;
/// assert!((e1 | e2) == FlagABC); // union
/// assert!((e1 & e2) == FlagC); // intersection
/// assert!((e1 - e2) == FlagA); // set difference
/// assert!(!e2 == FlagA); // set complement
/// }
/// ~~~
///
/// The generated `struct`s can also be extended with type and trait implementations:
///
/// ~~~rust
/// use std::fmt;
///
/// bitflags! {
/// flags Flags: u32 {
/// static FlagA = 0x00000001,
/// static FlagB = 0x00000010,
/// }
/// }
///
/// impl Flags {
/// pub fn clear(&mut self) {
/// self.bits = 0; // The `bits` field can be accessed from within the
/// // same module where the `bitflags!` macro was invoked.
/// }
/// }
///
/// impl fmt::Show for Flags {
/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
/// write!(f, "hi!")
/// }
/// }
///
/// fn main() {
/// let mut flags = FlagA | FlagB;
/// flags.clear();
/// assert!(flags.is_empty());
/// assert_eq!(format!("{}", flags).as_slice(), "hi!");
/// }
/// ~~~
///
/// # Attributes
///
/// Attributes can be attached to the generated `struct` by placing them
/// before the `flags` keyword.
///
/// # Derived traits
///
/// The `PartialEq` and `Clone` traits are automatically derived for the `struct` using
/// the `deriving` attribute. Additional traits can be derived by providing an
/// explicit `deriving` attribute on `flags`.
///
/// # Operators
///
/// The following operator traits are implemented for the generated `struct`:
///
/// - `BitOr`: union
/// - `BitAnd`: intersection
/// - `Sub`: set difference
/// - `Not`: set complement
///
/// # Methods
///
/// The following methods are defined for the generated `struct`:
///
/// - `empty`: an empty set of flags
/// - `all`: the set of all flags
/// - `bits`: the raw value of the flags currently stored
/// - `is_empty`: `true` if no flags are currently stored
/// - `is_all`: `true` if all flags are currently set
/// - `intersects`: `true` if there are flags common to both `self` and `other`
/// - `contains`: `true` all of the flags in `other` are contained within `self`
/// - `insert`: inserts the specified flags in-place
/// - `remove`: removes the specified flags in-place
#[macro_export]
macro_rules! bitflags(
macro_rules! bitflags {
($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
$($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+
}) => (
}) => {
#[deriving(PartialEq, Eq, Clone, PartialOrd, Ord, Hash)]
$(#[$attr])*
pub struct $BitFlags {
Expand Down Expand Up @@ -215,25 +216,43 @@ macro_rules! bitflags(
$BitFlags { bits: !self.bits } & $BitFlags::all()
}
}
)
)
};
($(#[$attr:meta])* flags $BitFlags:ident: $T:ty {
$($(#[$Flag_attr:meta])* static $Flag:ident = $value:expr),+,
}) => {
bitflags! {
$(#[$attr])*
flags $BitFlags: u32 {
$($(#[$Flag_attr])* static $Flag = $value),+
}
}
};
}

#[cfg(test)]
mod tests {
use hash;
use option::{Some, None};
use ops::{BitOr, BitAnd, Sub, Not};

bitflags!(
bitflags! {
#[doc = "> The first principle is that you must not fool yourself — and"]
#[doc = "> you are the easiest person to fool."]
#[doc = "> "]
#[doc = "> - Richard Feynman"]
flags Flags: u32 {
static FlagA = 0x00000001,
#[doc = "<pcwalton> macros are way better at generating code than trans is"]
static FlagB = 0x00000010,
static FlagC = 0x00000100,
#[doc = "* cmr bed"]
#[doc = "* strcat table"]
#[doc = "<strcat> wait what?"]
static FlagABC = FlagA.bits
| FlagB.bits
| FlagC.bits
| FlagC.bits,
}
)
}

#[test]
fn test_bits(){
Expand Down
24 changes: 12 additions & 12 deletions src/libstd/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1794,9 +1794,9 @@ pub struct UnstableFileStat {
pub gen: u64,
}

bitflags!(
#[doc="A set of permissions for a file or directory is represented
by a set of flags which are or'd together."]
bitflags! {
#[doc = "A set of permissions for a file or directory is represented"]
#[doc = "by a set of flags which are or'd together."]
flags FilePermission: u32 {
static UserRead = 0o400,
static UserWrite = 0o200,
Expand All @@ -1812,23 +1812,23 @@ by a set of flags which are or'd together."]
static GroupRWX = GroupRead.bits | GroupWrite.bits | GroupExecute.bits,
static OtherRWX = OtherRead.bits | OtherWrite.bits | OtherExecute.bits,

#[doc="Permissions for user owned files, equivalent to 0644 on
unix-like systems."]
#[doc = "Permissions for user owned files, equivalent to 0644 on"]
#[doc = "unix-like systems."]
static UserFile = UserRead.bits | UserWrite.bits | GroupRead.bits | OtherRead.bits,

#[doc="Permissions for user owned directories, equivalent to 0755 on
unix-like systems."]
#[doc = "Permissions for user owned directories, equivalent to 0755 on"]
#[doc = "unix-like systems."]
static UserDir = UserRWX.bits | GroupRead.bits | GroupExecute.bits |
OtherRead.bits | OtherExecute.bits,

#[doc="Permissions for user owned executables, equivalent to 0755
on unix-like systems."]
#[doc = "Permissions for user owned executables, equivalent to 0755"]
#[doc = "on unix-like systems."]
static UserExec = UserDir.bits,

#[doc="All possible permissions enabled."]
static AllPermissions = UserRWX.bits | GroupRWX.bits | OtherRWX.bits
#[doc = "All possible permissions enabled."]
static AllPermissions = UserRWX.bits | GroupRWX.bits | OtherRWX.bits,
}
)
}

impl Default for FilePermission {
#[inline]
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ mod std {
pub use fmt; // used for any formatting strings
pub use io; // used for println!()
pub use local_data; // used for local_data_key!()
pub use option; // used for bitflags!()
pub use option; // used for bitflags!{}
pub use rt; // used for fail!()
pub use vec; // used for vec![]

Expand Down