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 /// This method will return `true` if any unknown bits are set. contains_unknown_bits(&self) -> bool156 fn contains_unknown_bits(&self) -> bool { 157 Self::all().bits() & self.bits() != self.bits() 158 } 159 160 /// Get the underlying bits value. 161 /// 162 /// The returned value is exactly the bits set in this flags value. bits(&self) -> Self::Bits163 fn bits(&self) -> Self::Bits; 164 165 /// Convert from a bits value. 166 /// 167 /// This method will return `None` if any unknown bits are set. from_bits(bits: Self::Bits) -> Option<Self>168 fn from_bits(bits: Self::Bits) -> Option<Self> { 169 let truncated = Self::from_bits_truncate(bits); 170 171 if truncated.bits() == bits { 172 Some(truncated) 173 } else { 174 None 175 } 176 } 177 178 /// Convert from a bits value, unsetting any unknown bits. from_bits_truncate(bits: Self::Bits) -> Self179 fn from_bits_truncate(bits: Self::Bits) -> Self { 180 Self::from_bits_retain(bits & Self::all().bits()) 181 } 182 183 /// Convert from a bits value exactly. from_bits_retain(bits: Self::Bits) -> Self184 fn from_bits_retain(bits: Self::Bits) -> Self; 185 186 /// Get a flags value with the bits of a flag with the given name set. 187 /// 188 /// This method will return `None` if `name` is empty or doesn't 189 /// correspond to any named flag. from_name(name: &str) -> Option<Self>190 fn from_name(name: &str) -> Option<Self> { 191 // Don't parse empty names as empty flags 192 if name.is_empty() { 193 return None; 194 } 195 196 for flag in Self::FLAGS { 197 if flag.name() == name { 198 return Some(Self::from_bits_retain(flag.value().bits())); 199 } 200 } 201 202 None 203 } 204 205 /// Yield a set of contained flags values. 206 /// 207 /// Each yielded flags value will correspond to a defined named flag. Any unknown bits 208 /// will be yielded together as a final flags value. iter(&self) -> iter::Iter<Self>209 fn iter(&self) -> iter::Iter<Self> { 210 iter::Iter::new(self) 211 } 212 213 /// Yield a set of contained named flags values. 214 /// 215 /// This method is like [`Flags::iter`], except only yields bits in contained named flags. 216 /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded. iter_names(&self) -> iter::IterNames<Self>217 fn iter_names(&self) -> iter::IterNames<Self> { 218 iter::IterNames::new(self) 219 } 220 221 /// Whether all bits in this flags value are unset. is_empty(&self) -> bool222 fn is_empty(&self) -> bool { 223 self.bits() == Self::Bits::EMPTY 224 } 225 226 /// Whether all known bits in this flags value are set. is_all(&self) -> bool227 fn is_all(&self) -> bool { 228 // NOTE: We check against `Self::all` here, not `Self::Bits::ALL` 229 // because the set of all flags may not use all bits 230 Self::all().bits() | self.bits() == self.bits() 231 } 232 233 /// 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,234 fn intersects(&self, other: Self) -> bool 235 where 236 Self: Sized, 237 { 238 self.bits() & other.bits() != Self::Bits::EMPTY 239 } 240 241 /// 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,242 fn contains(&self, other: Self) -> bool 243 where 244 Self: Sized, 245 { 246 self.bits() & other.bits() == other.bits() 247 } 248 249 /// Remove any unknown bits from the flags. truncate(&mut self) where Self: Sized,250 fn truncate(&mut self) 251 where 252 Self: Sized, 253 { 254 *self = Self::from_bits_truncate(self.bits()); 255 } 256 257 /// The bitwise or (`|`) of the bits in two flags values. insert(&mut self, other: Self) where Self: Sized,258 fn insert(&mut self, other: Self) 259 where 260 Self: Sized, 261 { 262 *self = Self::from_bits_retain(self.bits()).union(other); 263 } 264 265 /// The intersection of a source flags value with the complement of a target flags value (`&!`). 266 /// 267 /// This method is not equivalent to `self & !other` when `other` has unknown bits set. 268 /// `remove` won't truncate `other`, but the `!` operator will. remove(&mut self, other: Self) where Self: Sized,269 fn remove(&mut self, other: Self) 270 where 271 Self: Sized, 272 { 273 *self = Self::from_bits_retain(self.bits()).difference(other); 274 } 275 276 /// The bitwise exclusive-or (`^`) of the bits in two flags values. toggle(&mut self, other: Self) where Self: Sized,277 fn toggle(&mut self, other: Self) 278 where 279 Self: Sized, 280 { 281 *self = Self::from_bits_retain(self.bits()).symmetric_difference(other); 282 } 283 284 /// Call [`Flags::insert`] when `value` is `true` or [`Flags::remove`] when `value` is `false`. set(&mut self, other: Self, value: bool) where Self: Sized,285 fn set(&mut self, other: Self, value: bool) 286 where 287 Self: Sized, 288 { 289 if value { 290 self.insert(other); 291 } else { 292 self.remove(other); 293 } 294 } 295 296 /// Unsets all bits in the flags. clear(&mut self) where Self: Sized,297 fn clear(&mut self) 298 where 299 Self: Sized, 300 { 301 *self = Self::empty(); 302 } 303 304 /// The bitwise and (`&`) of the bits in two flags values. 305 #[must_use] intersection(self, other: Self) -> Self306 fn intersection(self, other: Self) -> Self { 307 Self::from_bits_retain(self.bits() & other.bits()) 308 } 309 310 /// The bitwise or (`|`) of the bits in two flags values. 311 #[must_use] union(self, other: Self) -> Self312 fn union(self, other: Self) -> Self { 313 Self::from_bits_retain(self.bits() | other.bits()) 314 } 315 316 /// The intersection of a source flags value with the complement of a target flags value (`&!`). 317 /// 318 /// This method is not equivalent to `self & !other` when `other` has unknown bits set. 319 /// `difference` won't truncate `other`, but the `!` operator will. 320 #[must_use] difference(self, other: Self) -> Self321 fn difference(self, other: Self) -> Self { 322 Self::from_bits_retain(self.bits() & !other.bits()) 323 } 324 325 /// The bitwise exclusive-or (`^`) of the bits in two flags values. 326 #[must_use] symmetric_difference(self, other: Self) -> Self327 fn symmetric_difference(self, other: Self) -> Self { 328 Self::from_bits_retain(self.bits() ^ other.bits()) 329 } 330 331 /// The bitwise negation (`!`) of the bits in a flags value, truncating the result. 332 #[must_use] complement(self) -> Self333 fn complement(self) -> Self { 334 Self::from_bits_truncate(!self.bits()) 335 } 336 } 337 338 /** 339 A bits type that can be used as storage for a flags type. 340 */ 341 pub trait Bits: 342 Clone 343 + Copy 344 + PartialEq 345 + BitAnd<Output = Self> 346 + BitOr<Output = Self> 347 + BitXor<Output = Self> 348 + Not<Output = Self> 349 + Sized 350 + 'static 351 { 352 /// A value with all bits unset. 353 const EMPTY: Self; 354 355 /// A value with all bits set. 356 const ALL: Self; 357 } 358 359 // Not re-exported: prevent custom `Bits` impls being used in the `bitflags!` macro, 360 // or they may fail to compile based on crate features 361 pub trait Primitive {} 362 363 macro_rules! impl_bits { 364 ($($u:ty, $i:ty,)*) => { 365 $( 366 impl Bits for $u { 367 const EMPTY: $u = 0; 368 const ALL: $u = <$u>::MAX; 369 } 370 371 impl Bits for $i { 372 const EMPTY: $i = 0; 373 const ALL: $i = <$u>::MAX as $i; 374 } 375 376 impl ParseHex for $u { 377 fn parse_hex(input: &str) -> Result<Self, ParseError> { 378 <$u>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input)) 379 } 380 } 381 382 impl ParseHex for $i { 383 fn parse_hex(input: &str) -> Result<Self, ParseError> { 384 <$i>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input)) 385 } 386 } 387 388 impl WriteHex for $u { 389 fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result { 390 write!(writer, "{:x}", self) 391 } 392 } 393 394 impl WriteHex for $i { 395 fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result { 396 write!(writer, "{:x}", self) 397 } 398 } 399 400 impl Primitive for $i {} 401 impl Primitive for $u {} 402 )* 403 } 404 } 405 406 impl_bits! { 407 u8, i8, 408 u16, i16, 409 u32, i32, 410 u64, i64, 411 u128, i128, 412 usize, isize, 413 } 414 415 /// A trait for referencing the `bitflags`-owned internal type 416 /// without exposing it publicly. 417 pub trait PublicFlags { 418 /// The type of the underlying storage. 419 type Primitive: Primitive; 420 421 /// The type of the internal field on the generated flags type. 422 type Internal; 423 } 424 425 #[doc(hidden)] 426 #[deprecated(note = "use the `Flags` trait instead")] 427 pub trait BitFlags: ImplementedByBitFlagsMacro + Flags { 428 /// An iterator over enabled flags in an instance of the type. 429 type Iter: Iterator<Item = Self>; 430 431 /// An iterator over the raw names and bits for enabled flags in an instance of the type. 432 type IterNames: Iterator<Item = (&'static str, Self)>; 433 } 434 435 #[allow(deprecated)] 436 impl<B: Flags> BitFlags for B { 437 type Iter = iter::Iter<Self>; 438 type IterNames = iter::IterNames<Self>; 439 } 440 441 impl<B: Flags> ImplementedByBitFlagsMacro for B {} 442 443 /// A marker trait that signals that an implementation of `BitFlags` came from the `bitflags!` macro. 444 /// 445 /// There's nothing stopping an end-user from implementing this trait, but we don't guarantee their 446 /// manual implementations won't break between non-breaking releases. 447 #[doc(hidden)] 448 pub trait ImplementedByBitFlagsMacro {} 449 450 pub(crate) mod __private { 451 pub use super::{ImplementedByBitFlagsMacro, PublicFlags}; 452 } 453