1use core::{
2 fmt,
3 ops::{BitAnd, BitOr, BitXor, Not},
4};
5
6use crate::{
7 iter,
8 parser::{ParseError, ParseHex, WriteHex},
9};
10
11#[derive(#[automatically_derived]
impl<B: ::core::fmt::Debug> ::core::fmt::Debug for Flag<B> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "Flag", "name",
&self.name, "value", &&self.value)
}
}Debug)]
15pub struct Flag<B> {
16 name: &'static str,
17 value: B,
18}
19
20impl<B> Flag<B> {
21 pub const fn new(name: &'static str, value: B) -> Self {
27 Flag { name, value }
28 }
29
30 pub const fn name(&self) -> &'static str {
36 self.name
37 }
38
39 pub const fn value(&self) -> &B {
43 &self.value
44 }
45
46 pub const fn is_named(&self) -> bool {
52 !self.name.is_empty()
53 }
54
55 pub const fn is_unnamed(&self) -> bool {
61 self.name.is_empty()
62 }
63}
64
65pub trait Flags: Sized + 'static {
133 const FLAGS: &'static [Flag<Self>];
135
136 type Bits: Bits;
138
139 fn empty() -> Self {
141 Self::from_bits_retain(Self::Bits::EMPTY)
142 }
143
144 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 fn all_named() -> Self {
159 Self::from_bits_retain(
160 Self::FLAGS
161 .iter()
162 .filter(|f| !f.name().is_empty())
163 .fold(Self::empty().bits(), |acc, f| acc | f.value().bits()),
164 )
165 }
166
167 fn known_bits(&self) -> Self::Bits {
169 self.bits() & Self::all().bits()
170 }
171
172 fn unknown_bits(&self) -> Self::Bits {
174 self.bits() & !Self::all().bits()
175 }
176
177 fn contains_unknown_bits(&self) -> bool {
179 self.unknown_bits() != Self::Bits::EMPTY
180 }
181
182 fn bits(&self) -> Self::Bits;
186
187 fn from_bits(bits: Self::Bits) -> Option<Self> {
191 let truncated = Self::from_bits_truncate(bits);
192
193 if truncated.bits() == bits {
194 Some(truncated)
195 } else {
196 None
197 }
198 }
199
200 fn from_bits_truncate(bits: Self::Bits) -> Self {
202 Self::from_bits_retain(bits & Self::all().bits())
203 }
204
205 fn from_bits_retain(bits: Self::Bits) -> Self;
207
208 fn from_name(name: &str) -> Option<Self> {
213 if name.is_empty() {
215 return None;
216 }
217
218 for flag in Self::FLAGS {
219 if flag.name() == name {
220 return Some(Self::from_bits_retain(flag.value().bits()));
221 }
222 }
223
224 None
225 }
226
227 fn iter(&self) -> iter::Iter<Self> {
232 iter::Iter::new(self)
233 }
234
235 fn iter_names(&self) -> iter::IterNames<Self> {
240 iter::IterNames::new(self)
241 }
242
243 fn iter_defined_names() -> iter::IterDefinedNames<Self> {
245 iter::IterDefinedNames::new()
246 }
247
248 fn iter_equal_names(&self) -> iter::IterEqualNames<Self> {
253 iter::IterEqualNames::new(self)
254 }
255
256 fn is_empty(&self) -> bool {
258 self.bits() == Self::Bits::EMPTY
259 }
260
261 fn is_all(&self) -> bool {
263 Self::all().bits() | self.bits() == self.bits()
266 }
267
268 fn intersects(&self, other: Self) -> bool
270 where
271 Self: Sized,
272 {
273 self.bits() & other.bits() != Self::Bits::EMPTY
274 }
275
276 fn contains(&self, other: Self) -> bool
278 where
279 Self: Sized,
280 {
281 self.bits() & other.bits() == other.bits()
282 }
283
284 fn truncate(&mut self)
286 where
287 Self: Sized,
288 {
289 *self = Self::from_bits_truncate(self.bits());
290 }
291
292 fn insert(&mut self, other: Self)
294 where
295 Self: Sized,
296 {
297 *self = Self::from_bits_retain(self.bits()).union(other);
298 }
299
300 fn remove(&mut self, other: Self)
305 where
306 Self: Sized,
307 {
308 *self = Self::from_bits_retain(self.bits()).difference(other);
309 }
310
311 fn toggle(&mut self, other: Self)
313 where
314 Self: Sized,
315 {
316 *self = Self::from_bits_retain(self.bits()).symmetric_difference(other);
317 }
318
319 fn set(&mut self, other: Self, value: bool)
321 where
322 Self: Sized,
323 {
324 if value {
325 self.insert(other);
326 } else {
327 self.remove(other);
328 }
329 }
330
331 fn clear(&mut self)
333 where
334 Self: Sized,
335 {
336 *self = Self::empty();
337 }
338
339 #[must_use]
341 fn intersection(self, other: Self) -> Self {
342 Self::from_bits_retain(self.bits() & other.bits())
343 }
344
345 #[must_use]
347 fn union(self, other: Self) -> Self {
348 Self::from_bits_retain(self.bits() | other.bits())
349 }
350
351 #[must_use]
356 fn difference(self, other: Self) -> Self {
357 Self::from_bits_retain(self.bits() & !other.bits())
358 }
359
360 #[must_use]
362 fn symmetric_difference(self, other: Self) -> Self {
363 Self::from_bits_retain(self.bits() ^ other.bits())
364 }
365
366 #[must_use]
368 fn complement(self) -> Self {
369 Self::from_bits_truncate(!self.bits())
370 }
371}
372
373pub trait Bits:
377 Clone
378 + Copy
379 + PartialEq
380 + BitAnd<Output = Self>
381 + BitOr<Output = Self>
382 + BitXor<Output = Self>
383 + Not<Output = Self>
384 + Sized
385 + 'static
386{
387 const EMPTY: Self;
389
390 const ALL: Self;
392}
393
394pub trait Primitive {}
397
398macro_rules! impl_bits {
399 ($($u:ty, $i:ty,)*) => {
400 $(
401 impl Bits for $u {
402 const EMPTY: $u = 0;
403 const ALL: $u = <$u>::MAX;
404 }
405
406 impl Bits for $i {
407 const EMPTY: $i = 0;
408 const ALL: $i = <$u>::MAX as $i;
409 }
410
411 impl ParseHex for $u {
412 fn parse_hex(input: &str) -> Result<Self, ParseError> {
413 <$u>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input))
414 }
415 }
416
417 impl ParseHex for $i {
418 fn parse_hex(input: &str) -> Result<Self, ParseError> {
419 <$i>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input))
420 }
421 }
422
423 impl WriteHex for $u {
424 fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
425 write!(writer, "{:x}", self)
426 }
427 }
428
429 impl WriteHex for $i {
430 fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
431 write!(writer, "{:x}", self)
432 }
433 }
434
435 impl Primitive for $i {}
436 impl Primitive for $u {}
437 )*
438 }
439}
440
441impl Bits for u8 {
const EMPTY: u8 = 0;
const ALL: u8 = <u8>::MAX;
}
impl Bits for i8 {
const EMPTY: i8 = 0;
const ALL: i8 = <u8>::MAX as i8;
}
impl ParseHex for u8 {
fn parse_hex(input: &str) -> Result<Self, ParseError> {
<u8>::from_str_radix(input,
16).map_err(|_| ParseError::invalid_hex_flag(input))
}
}
impl ParseHex for i8 {
fn parse_hex(input: &str) -> Result<Self, ParseError> {
<i8>::from_str_radix(input,
16).map_err(|_| ParseError::invalid_hex_flag(input))
}
}
impl WriteHex for u8 {
fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
writer.write_fmt(format_args!("{0:x}", self))
}
}
impl WriteHex for i8 {
fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
writer.write_fmt(format_args!("{0:x}", self))
}
}
impl Primitive for i8 {}
impl Primitive for u8 {}
impl Bits for u16 {
const EMPTY: u16 = 0;
const ALL: u16 = <u16>::MAX;
}
impl Bits for i16 {
const EMPTY: i16 = 0;
const ALL: i16 = <u16>::MAX as i16;
}
impl ParseHex for u16 {
fn parse_hex(input: &str) -> Result<Self, ParseError> {
<u16>::from_str_radix(input,
16).map_err(|_| ParseError::invalid_hex_flag(input))
}
}
impl ParseHex for i16 {
fn parse_hex(input: &str) -> Result<Self, ParseError> {
<i16>::from_str_radix(input,
16).map_err(|_| ParseError::invalid_hex_flag(input))
}
}
impl WriteHex for u16 {
fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
writer.write_fmt(format_args!("{0:x}", self))
}
}
impl WriteHex for i16 {
fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
writer.write_fmt(format_args!("{0:x}", self))
}
}
impl Primitive for i16 {}
impl Primitive for u16 {}
impl Bits for u32 {
const EMPTY: u32 = 0;
const ALL: u32 = <u32>::MAX;
}
impl Bits for i32 {
const EMPTY: i32 = 0;
const ALL: i32 = <u32>::MAX as i32;
}
impl ParseHex for u32 {
fn parse_hex(input: &str) -> Result<Self, ParseError> {
<u32>::from_str_radix(input,
16).map_err(|_| ParseError::invalid_hex_flag(input))
}
}
impl ParseHex for i32 {
fn parse_hex(input: &str) -> Result<Self, ParseError> {
<i32>::from_str_radix(input,
16).map_err(|_| ParseError::invalid_hex_flag(input))
}
}
impl WriteHex for u32 {
fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
writer.write_fmt(format_args!("{0:x}", self))
}
}
impl WriteHex for i32 {
fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
writer.write_fmt(format_args!("{0:x}", self))
}
}
impl Primitive for i32 {}
impl Primitive for u32 {}
impl Bits for u64 {
const EMPTY: u64 = 0;
const ALL: u64 = <u64>::MAX;
}
impl Bits for i64 {
const EMPTY: i64 = 0;
const ALL: i64 = <u64>::MAX as i64;
}
impl ParseHex for u64 {
fn parse_hex(input: &str) -> Result<Self, ParseError> {
<u64>::from_str_radix(input,
16).map_err(|_| ParseError::invalid_hex_flag(input))
}
}
impl ParseHex for i64 {
fn parse_hex(input: &str) -> Result<Self, ParseError> {
<i64>::from_str_radix(input,
16).map_err(|_| ParseError::invalid_hex_flag(input))
}
}
impl WriteHex for u64 {
fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
writer.write_fmt(format_args!("{0:x}", self))
}
}
impl WriteHex for i64 {
fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
writer.write_fmt(format_args!("{0:x}", self))
}
}
impl Primitive for i64 {}
impl Primitive for u64 {}
impl Bits for u128 {
const EMPTY: u128 = 0;
const ALL: u128 = <u128>::MAX;
}
impl Bits for i128 {
const EMPTY: i128 = 0;
const ALL: i128 = <u128>::MAX as i128;
}
impl ParseHex for u128 {
fn parse_hex(input: &str) -> Result<Self, ParseError> {
<u128>::from_str_radix(input,
16).map_err(|_| ParseError::invalid_hex_flag(input))
}
}
impl ParseHex for i128 {
fn parse_hex(input: &str) -> Result<Self, ParseError> {
<i128>::from_str_radix(input,
16).map_err(|_| ParseError::invalid_hex_flag(input))
}
}
impl WriteHex for u128 {
fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
writer.write_fmt(format_args!("{0:x}", self))
}
}
impl WriteHex for i128 {
fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
writer.write_fmt(format_args!("{0:x}", self))
}
}
impl Primitive for i128 {}
impl Primitive for u128 {}
impl Bits for usize {
const EMPTY: usize = 0;
const ALL: usize = <usize>::MAX;
}
impl Bits for isize {
const EMPTY: isize = 0;
const ALL: isize = <usize>::MAX as isize;
}
impl ParseHex for usize {
fn parse_hex(input: &str) -> Result<Self, ParseError> {
<usize>::from_str_radix(input,
16).map_err(|_| ParseError::invalid_hex_flag(input))
}
}
impl ParseHex for isize {
fn parse_hex(input: &str) -> Result<Self, ParseError> {
<isize>::from_str_radix(input,
16).map_err(|_| ParseError::invalid_hex_flag(input))
}
}
impl WriteHex for usize {
fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
writer.write_fmt(format_args!("{0:x}", self))
}
}
impl WriteHex for isize {
fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
writer.write_fmt(format_args!("{0:x}", self))
}
}
impl Primitive for isize {}
impl Primitive for usize {}impl_bits! {
442 u8, i8,
443 u16, i16,
444 u32, i32,
445 u64, i64,
446 u128, i128,
447 usize, isize,
448}
449
450pub trait PublicFlags {
453 type Primitive: Primitive;
455
456 type Internal;
458}
459
460#[doc(hidden)]
461#[deprecated(note = "use the `Flags` trait instead")]
462pub trait BitFlags: ImplementedByBitFlagsMacro + Flags {
463 type Iter: Iterator<Item = Self>;
465
466 type IterNames: Iterator<Item = (&'static str, Self)>;
468}
469
470#[allow(deprecated)]
471impl<B: Flags> BitFlags for B {
472 type Iter = iter::Iter<Self>;
473 type IterNames = iter::IterNames<Self>;
474}
475
476impl<B: Flags> ImplementedByBitFlagsMacro for B {}
477
478#[doc(hidden)]
483pub trait ImplementedByBitFlagsMacro {}
484
485pub(crate) mod __private {
486 pub use super::{ImplementedByBitFlagsMacro, PublicFlags};
487}