tiny_bit_flags/lib.rs
1//! Generate bit-flags struct and methods.
2//!
3//! It's very simple and easy to use. See the example below for details.
4//!
5//! # Usage
6//!
7//! Import this crate and `paste` to your `Cargo.toml`:
8//!
9//! ```toml
10//! [dependencies]
11//! tiny-bit-flags = "0.1"
12//! paste = "1.0"
13//! ```
14//!
15//! Invoke the `tiny_bit_flags!` macro to define flags:
16//!
17//! ```rust
18//! tiny_bit_flags::tiny_bit_flags! {
19//! struct PrimFlags: u32 { // FORMAT: struct <StructName>: <InnerType>
20//! // list flags below
21//! const WRITABLE = 0b00000001;
22//! const EXECUTABLE = 0b00000010;
23//! }
24//! }
25//! ```
26//!
27//! This actually generates the following code:
28//!
29//! ```rust,ignore
30//! // struct
31//! struct PrimFlags(u32);
32//!
33//! impl PrimFlags {
34//! // constant values
35//! const WRITABLE: u32 = 0b00000001;
36//! const EXECUTABLE: u32 = 0b00000010;
37//! // checking methods
38//! const fn is_writable(&self) -> bool { ... }
39//! const fn is_executable(&self) -> bool { ... }
40//! // setting methods
41//! const fn set_writable(&mut self) { ... }
42//! const fn set_executable(&mut self) { ... }
43//! // clearing methods
44//! const fn clear_writable(&mut self) { ... }
45//! const fn clear_executable(&mut self) { ... }
46//! }
47//! ```
48//!
49//! Then you can use them in your program:
50//!
51//! ```rust,ignore
52//! let mut f = PrimFlags(PrimFlags::WRITABLE); // initialize
53//! assert!(f.is_writable()); // check flag
54//! assert!(!f.is_executable());
55//!
56//! f.clear_writable(); // clear flag
57//! assert!(!f.is_writable());
58//!
59//! f.set_executable(); // set flag
60//! assert!(f.is_executable());
61//! ```
62//!
63//! You can use `pub` before `struct` to make all above to be public:
64//!
65//! ```diff
66//! tiny_bit_flags! {
67//! + pub struct PrimFlags: u32 {
68//! - struct PrimFlags: u32 {
69//! ```
70//!
71//! You can also derive some traits on the struct:
72//!
73//! ```diff
74//! tiny_bit_flags! {
75//! + #[derive(Copy, Clone, Debug, Default)]
76//! struct PrimFlags: u32 {
77//! ```
78
79/// Generate bit-flags struct and methods.
80///
81/// See module-level document for details.
82///
83/// Example:
84///
85/// ```rust
86/// tiny_bit_flags::tiny_bit_flags! {
87/// struct PrimFlags: u32 {
88/// const WRITABLE = 0b00000001;
89/// const EXECUTABLE = 0b00000010;
90/// }
91/// }
92///
93/// let mut f = PrimFlags(PrimFlags::WRITABLE); // initialize
94/// assert!(f.is_writable()); // check flag
95/// assert!(!f.is_executable());
96///
97/// f.clear_writable(); // clear flag
98/// assert!(!f.is_writable());
99///
100/// f.set_executable(); // set flag
101/// assert!(f.is_executable());
102/// ```
103///
104#[macro_export]
105macro_rules! tiny_bit_flags {
106 (
107 $(#[$outer:meta])*
108 $vis:vis struct $BitFlags:ident: $T:ty {
109 $(
110 $(#[$inner:ident $($args:tt)*])*
111 const $Flag:tt = $value:expr;
112 )*
113 }
114 ) => {
115 // struct
116 $(#[$outer])*
117 $vis struct $BitFlags($vis $T);
118
119 impl $BitFlags {
120 $(
121 // constant values
122 $(#[$inner $($args)*])*
123 $vis const $Flag: $T = $value;
124
125 // methods
126 paste::paste! {
127 $vis const fn [<is_ $Flag:lower>](&self) -> bool {
128 self.0 & $value != 0
129 }
130 $vis const fn [<set_ $Flag:lower>](&mut self) {
131 self.0 |= $value
132 }
133 $vis const fn [<clear_ $Flag:lower>](&mut self) {
134 self.0 &= !$value
135 }
136 }
137 )*
138 }
139 };
140}