1 use core::{ 2 fmt, 3 ops::{BitAnd, BitOr, BitXor, Not}, 4 }; 5 6 use crate::{ 7 iter, 8 parser::{ParseError, ParseHex, WriteHex}, 9 }; 10 11 /** 12 A defined flags value that may be named or unnamed. 13 */ 14 #[derive(Debug)] 15 pub struct Flag<B> { 16 name: &'static str, 17 value: B, 18 } 19 20 impl<B> Flag<B> { 21 /** 22 Define a flag. 23 24 If `name` is non-empty then the flag is named, otherwise it's unnamed. 25 */ new(name: &'static str, value: B) -> Self26 pub const fn new(name: &'static str, value: B) -> Self { 27 Flag { name, value } 28 } 29 30 /** 31 Get the name of this flag. 32 33 If the flag is unnamed then the returned string will be empty. 34 */ name(&self) -> &'static str35 pub const fn name(&self) -> &'static str { 36 self.name 37 } 38 39 /** 40 Get the flags value of this flag. 41 */ value(&self) -> &B42 pub const fn value(&self) -> &B { 43 &self.value 44 } 45 46 /** 47 Whether the flag is named. 48 49 If [`Flag::name`] returns a non-empty string then this method will return `true`. 50 */ is_named(&self) -> bool51 pub const fn is_named(&self) -> bool { 52 !self.name.is_empty() 53 } 54 55 /** 56 Whether the flag is unnamed. 57 58 If [`Flag::name`] returns a non-empty string then this method will return `false`. 59 */ is_unnamed(&self) -> bool60 pub const fn is_unnamed(&self) -> bool { 61 self.name.is_empty() 62 } 63 } 64 65 /** 66 A set of defined flags using a bits type as storage. 67 68 ## Implementing `Flags` 69 70 This trait is implemented by the [`bitflags`](macro.bitflags.html) macro: 71 72 ``` 73 use bitflags::bitflags; 74 75 bitflags! { 76 struct MyFlags: u8 { 77 const A = 1; 78 const B = 1 << 1; 79 } 80 } 81 ``` 82 83 It can also be implemented manually: 84 85 ``` 86 use bitflags::{Flag, Flags}; 87 88 struct MyFlags(u8); 89 90 impl Flags for MyFlags { 91 const FLAGS: &'static [Flag<Self>] = &[ 92 Flag::new("A", MyFlags(1)), 93 Flag::new("B", MyFlags(1 << 1)), 94 ]; 95 96 type Bits = u8; 97 98 fn from_bits_retain(bits: Self::Bits) -> Self { 99 MyFlags(bits) 100 } 101 102 fn bits(&self) -> Self::Bits { 103 self.0 104 } 105 } 106 ``` 107 108 ## Using `Flags` 109 110 The `Flags` trait can be used generically to work with any flags types. In this example, 111 we can count the number of defined named flags: 112 113 ``` 114 # use bitflags::{bitflags, Flags}; 115 fn defined_flags<F: Flags>() -> usize { 116 F::FLAGS.iter().filter(|f| f.is_named()).count() 117 } 118 119 bitflags! { 120 struct MyFlags: u8 { 121 const A = 1; 122 const B = 1 << 1; 123 const C = 1 << 2; 124 125 const _ = !0; 126 } 127 } 128 129 assert_eq!(3, defined_flags::<MyFlags>()); 130 ``` 131 */ 132 pub trait Flags: Sized + 'static { 133 /// The set of defined flags. 134 const FLAGS: &'static [Flag<Self>]; 135 136 /// The underlying bits type. 137 type Bits: Bits; 138 139 /// Get a flags value with all bits unset. empty() -> Self140 fn empty() -> Self { 141 Self::from_bits_retain(Self::Bits::EMPTY) 142 } 143 144 /// Get a flags value with all known bits set. all() -> Self145 fn all() -> Self { 146 let mut truncated = Self::Bits::EMPTY; 147 148 for flag in Self::FLAGS.iter() { 149 truncated = truncated | flag.value().bits(); 150 } 151 152 Self::from_bits_retain(truncated) 153 } 154 155 /// Get the underlying bits value. 156 /// 157 /// The returned value is exactly the bits set in this flags value. bits(&self) -> Self::Bits158 fn bits(&self) -> Self::Bits; 159 160 /// Convert from a bits value. 161 /// 162 /// This method will return `None` if any unknown bits are set. from_bits(bits: Self::Bits) -> Option<Self>163 fn from_bits(bits: Self::Bits) -> Option<Self> { 164 let truncated = Self::from_bits_truncate(bits); 165 166 if truncated.bits() == bits { 167 Some(truncated) 168 } else { 169 None 170 } 171 } 172 173 /// Convert from a bits value, unsetting any unknown bits. from_bits_truncate(bits: Self::Bits) -> Self174 fn from_bits_truncate(bits: Self::Bits) -> Self { 175 Self::from_bits_retain(bits & Self::all().bits()) 176 } 177 178 /// Convert from a bits value exactly. from_bits_retain(bits: Self::Bits) -> Self179 fn from_bits_retain(bits: Self::Bits) -> Self; 180 181 /// Get a flags value with the bits of a flag with the given name set. 182 /// 183 /// This method will return `None` if `name` is empty or doesn't 184 /// correspond to any named flag. from_name(name: &str) -> Option<Self>185 fn from_name(name: &str) -> Option<Self> { 186 // Don't parse empty names as empty flags 187 if name.is_empty() { 188 return None; 189 } 190 191 for flag in Self::FLAGS { 192 if flag.name() == name { 193 return Some(Self::from_bits_retain(flag.value().bits())); 194 } 195 } 196 197 None 198 } 199 200 /// Yield a set of contained flags values. 201 /// 202 /// Each yielded flags value will correspond to a defined named flag. Any unknown bits 203 /// will be yielded together as a final flags value. iter(&self) -> iter::Iter<Self>204 fn iter(&self) -> iter::Iter<Self> { 205 iter::Iter::new(self) 206 } 207 208 /// Yield a set of contained named flags values. 209 /// 210 /// This method is like [`Flags::iter`], except only yields bits in contained named flags. 211 /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded. iter_names(&self) -> iter::IterNames<Self>212 fn iter_names(&self) -> iter::IterNames<Self> { 213 iter::IterNames::new(self) 214 } 215 216 /// Whether all bits in this flags value are unset. is_empty(&self) -> bool217 fn is_empty(&self) -> bool { 218 self.bits() == Self::Bits::EMPTY 219 } 220 221 /// Whether all known bits in this flags value are set. is_all(&self) -> bool222 fn is_all(&self) -> bool { 223 // NOTE: We check against `Self::all` here, not `Self::Bits::ALL` 224 // because the set of all flags may not use all bits 225 Self::all().bits() | self.bits() == self.bits() 226 } 227 228 /// Whether any set bits in a source flags value are also set in a target flags value. intersects(&self, other: Self) -> bool where Self: Sized,229 fn intersects(&self, other: Self) -> bool 230 where 231 Self: Sized, 232 { 233 self.bits() & other.bits() != Self::Bits::EMPTY 234 } 235 236 /// Whether all set bits in a source flags value are also set in a target flags value. contains(&self, other: Self) -> bool where Self: Sized,237 fn contains(&self, other: Self) -> bool 238 where 239 Self: Sized, 240 { 241 self.bits() & other.bits() == other.bits() 242 } 243 244 /// The bitwise or (`|`) of the bits in two flags values. insert(&mut self, other: Self) where Self: Sized,245 fn insert(&mut self, other: Self) 246 where 247 Self: Sized, 248 { 249 *self = Self::from_bits_retain(self.bits()).union(other); 250 } 251 252 /// The intersection of a source flags value with the complement of a target flags value (`&!`). 253 /// 254 /// This method is not equivalent to `self & !other` when `other` has unknown bits set. 255 /// `remove` won't truncate `other`, but the `!` operator will. remove(&mut self, other: Self) where Self: Sized,256 fn remove(&mut self, other: Self) 257 where 258 Self: Sized, 259 { 260 *self = Self::from_bits_retain(self.bits()).difference(other); 261 } 262 263 /// The bitwise exclusive-or (`^`) of the bits in two flags values. toggle(&mut self, other: Self) where Self: Sized,264 fn toggle(&mut self, other: Self) 265 where 266 Self: Sized, 267 { 268 *self = Self::from_bits_retain(self.bits()).symmetric_difference(other); 269 } 270 271 /// Call [`Flags::insert`] when `value` is `true` or [`Flags::remove`] when `value` is `false`. set(&mut self, other: Self, value: bool) where Self: Sized,272 fn set(&mut self, other: Self, value: bool) 273 where 274 Self: Sized, 275 { 276 if value { 277 self.insert(other); 278 } else { 279 self.remove(other); 280 } 281 } 282 283 /// The bitwise and (`&`) of the bits in two flags values. 284 #[must_use] intersection(self, other: Self) -> Self285 fn intersection(self, other: Self) -> Self { 286 Self::from_bits_retain(self.bits() & other.bits()) 287 } 288 289 /// The bitwise or (`|`) of the bits in two flags values. 290 #[must_use] union(self, other: Self) -> Self291 fn union(self, other: Self) -> Self { 292 Self::from_bits_retain(self.bits() | other.bits()) 293 } 294 295 /// The intersection of a source flags value with the complement of a target flags value (`&!`). 296 /// 297 /// This method is not equivalent to `self & !other` when `other` has unknown bits set. 298 /// `difference` won't truncate `other`, but the `!` operator will. 299 #[must_use] difference(self, other: Self) -> Self300 fn difference(self, other: Self) -> Self { 301 Self::from_bits_retain(self.bits() & !other.bits()) 302 } 303 304 /// The bitwise exclusive-or (`^`) of the bits in two flags values. 305 #[must_use] symmetric_difference(self, other: Self) -> Self306 fn symmetric_difference(self, other: Self) -> Self { 307 Self::from_bits_retain(self.bits() ^ other.bits()) 308 } 309 310 /// The bitwise negation (`!`) of the bits in a flags value, truncating the result. 311 #[must_use] complement(self) -> Self312 fn complement(self) -> Self { 313 Self::from_bits_truncate(!self.bits()) 314 } 315 } 316 317 /** 318 A bits type that can be used as storage for a flags type. 319 */ 320 pub trait Bits: 321 Clone 322 + Copy 323 + PartialEq 324 + BitAnd<Output = Self> 325 + BitOr<Output = Self> 326 + BitXor<Output = Self> 327 + Not<Output = Self> 328 + Sized 329 + 'static 330 { 331 /// A value with all bits unset. 332 const EMPTY: Self; 333 334 /// A value with all bits set. 335 const ALL: Self; 336 } 337 338 // Not re-exported: prevent custom `Bits` impls being used in the `bitflags!` macro, 339 // or they may fail to compile based on crate features 340 pub trait Primitive {} 341 342 macro_rules! impl_bits { 343 ($($u:ty, $i:ty,)*) => { 344 $( 345 impl Bits for $u { 346 const EMPTY: $u = 0; 347 const ALL: $u = <$u>::MAX; 348 } 349 350 impl Bits for $i { 351 const EMPTY: $i = 0; 352 const ALL: $i = <$u>::MAX as $i; 353 } 354 355 impl ParseHex for $u { 356 fn parse_hex(input: &str) -> Result<Self, ParseError> { 357 <$u>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input)) 358 } 359 } 360 361 impl ParseHex for $i { 362 fn parse_hex(input: &str) -> Result<Self, ParseError> { 363 <$i>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input)) 364 } 365 } 366 367 impl WriteHex for $u { 368 fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result { 369 write!(writer, "{:x}", self) 370 } 371 } 372 373 impl WriteHex for $i { 374 fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result { 375 write!(writer, "{:x}", self) 376 } 377 } 378 379 impl Primitive for $i {} 380 impl Primitive for $u {} 381 )* 382 } 383 } 384 385 impl_bits! { 386 u8, i8, 387 u16, i16, 388 u32, i32, 389 u64, i64, 390 u128, i128, 391 usize, isize, 392 } 393 394 /// A trait for referencing the `bitflags`-owned internal type 395 /// without exposing it publicly. 396 pub trait PublicFlags { 397 /// The type of the underlying storage. 398 type Primitive: Primitive; 399 400 /// The type of the internal field on the generated flags type. 401 type Internal; 402 } 403 404 #[doc(hidden)] 405 #[deprecated(note = "use the `Flags` trait instead")] 406 pub trait BitFlags: ImplementedByBitFlagsMacro + Flags { 407 /// An iterator over enabled flags in an instance of the type. 408 type Iter: Iterator<Item = Self>; 409 410 /// An iterator over the raw names and bits for enabled flags in an instance of the type. 411 type IterNames: Iterator<Item = (&'static str, Self)>; 412 } 413 414 #[allow(deprecated)] 415 impl<B: Flags> BitFlags for B { 416 type Iter = iter::Iter<Self>; 417 type IterNames = iter::IterNames<Self>; 418 } 419 420 impl<B: Flags> ImplementedByBitFlagsMacro for B {} 421 422 /// A marker trait that signals that an implementation of `BitFlags` came from the `bitflags!` macro. 423 /// 424 /// There's nothing stopping an end-user from implementing this trait, but we don't guarantee their 425 /// manual implementations won't break between non-breaking releases. 426 #[doc(hidden)] 427 pub trait ImplementedByBitFlagsMacro {} 428 429 pub(crate) mod __private { 430 pub use super::{ImplementedByBitFlagsMacro, PublicFlags}; 431 } 432