1use core::{
2 fmt,
3 ops::{BitAnd, BitOr, BitXor, Not},
4};
5
6use crate::{
7 iter,
8 parser::{ParseError, ParseHex, WriteHex},
9};
10
11)]
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 contains_unknown_bits(&self) -> bool {
157 Self::all().bits() & self.bits() != self.bits()
158 }
159
160 fn bits(&self) -> Self::Bits;
164
165 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 fn from_bits_truncate(bits: Self::Bits) -> Self {
180 Self::from_bits_retain(bits & Self::all().bits())
181 }
182
183 fn from_bits_retain(bits: Self::Bits) -> Self;
185
186 fn from_name(name: &str) -> Option<Self> {
191 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 fn iter(&self) -> iter::Iter<Self> {
210 iter::Iter::new(self)
211 }
212
213 fn iter_names(&self) -> iter::IterNames<Self> {
218 iter::IterNames::new(self)
219 }
220
221 fn iter_defined_names() -> iter::IterDefinedNames<Self> {
223 iter::IterDefinedNames::new()
224 }
225
226 fn is_empty(&self) -> bool {
228 self.bits() == Self::Bits::EMPTY
229 }
230
231 fn is_all(&self) -> bool {
233 Self::all().bits() | self.bits() == self.bits()
236 }
237
238 fn intersects(&self, other: Self) -> bool
240 where
241 Self: Sized,
242 {
243 self.bits() & other.bits() != Self::Bits::EMPTY
244 }
245
246 fn contains(&self, other: Self) -> bool
248 where
249 Self: Sized,
250 {
251 self.bits() & other.bits() == other.bits()
252 }
253
254 fn truncate(&mut self)
256 where
257 Self: Sized,
258 {
259 *self = Self::from_bits_truncate(self.bits());
260 }
261
262 fn insert(&mut self, other: Self)
264 where
265 Self: Sized,
266 {
267 *self = Self::from_bits_retain(self.bits()).union(other);
268 }
269
270 fn remove(&mut self, other: Self)
275 where
276 Self: Sized,
277 {
278 *self = Self::from_bits_retain(self.bits()).difference(other);
279 }
280
281 fn toggle(&mut self, other: Self)
283 where
284 Self: Sized,
285 {
286 *self = Self::from_bits_retain(self.bits()).symmetric_difference(other);
287 }
288
289 fn set(&mut self, other: Self, value: bool)
291 where
292 Self: Sized,
293 {
294 if value {
295 self.insert(other);
296 } else {
297 self.remove(other);
298 }
299 }
300
301 fn clear(&mut self)
303 where
304 Self: Sized,
305 {
306 *self = Self::empty();
307 }
308
309 #[must_use]
311 fn intersection(self, other: Self) -> Self {
312 Self::from_bits_retain(self.bits() & other.bits())
313 }
314
315 #[must_use]
317 fn union(self, other: Self) -> Self {
318 Self::from_bits_retain(self.bits() | other.bits())
319 }
320
321 #[must_use]
326 fn difference(self, other: Self) -> Self {
327 Self::from_bits_retain(self.bits() & !other.bits())
328 }
329
330 #[must_use]
332 fn symmetric_difference(self, other: Self) -> Self {
333 Self::from_bits_retain(self.bits() ^ other.bits())
334 }
335
336 #[must_use]
338 fn complement(self) -> Self {
339 Self::from_bits_truncate(!self.bits())
340 }
341}
342
343pub trait Bits:
347 Clone
348 + Copy
349 + PartialEq
350 + BitAnd<Output = Self>
351 + BitOr<Output = Self>
352 + BitXor<Output = Self>
353 + Not<Output = Self>
354 + Sized
355 + 'static
356{
357 const EMPTY: Self;
359
360 const ALL: Self;
362}
363
364pub trait Primitive {}
367
368macro_rules! impl_bits {
369 ($($u:ty, $i:ty,)*) => {
370 $(
371 impl Bits for $u {
372 const EMPTY: $u = 0;
373 const ALL: $u = <$u>::MAX;
374 }
375
376 impl Bits for $i {
377 const EMPTY: $i = 0;
378 const ALL: $i = <$u>::MAX as $i;
379 }
380
381 impl ParseHex for $u {
382 fn parse_hex(input: &str) -> Result<Self, ParseError> {
383 <$u>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input))
384 }
385 }
386
387 impl ParseHex for $i {
388 fn parse_hex(input: &str) -> Result<Self, ParseError> {
389 <$i>::from_str_radix(input, 16).map_err(|_| ParseError::invalid_hex_flag(input))
390 }
391 }
392
393 impl WriteHex for $u {
394 fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
395 write!(writer, "{:x}", self)
396 }
397 }
398
399 impl WriteHex for $i {
400 fn write_hex<W: fmt::Write>(&self, mut writer: W) -> fmt::Result {
401 write!(writer, "{:x}", self)
402 }
403 }
404
405 impl Primitive for $i {}
406 impl Primitive for $u {}
407 )*
408 }
409}
410
411impl 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! {
412 u8, i8,
413 u16, i16,
414 u32, i32,
415 u64, i64,
416 u128, i128,
417 usize, isize,
418}
419
420pub trait PublicFlags {
423 type Primitive: Primitive;
425
426 type Internal;
428}
429
430#[doc(hidden)]
431#[deprecated(note = "use the `Flags` trait instead")]
432pub trait BitFlags: ImplementedByBitFlagsMacro + Flags {
433 type Iter: Iterator<Item = Self>;
435
436 type IterNames: Iterator<Item = (&'static str, Self)>;
438}
439
440#[allow(deprecated)]
441impl<B: Flags> BitFlags for B {
442 type Iter = iter::Iter<Self>;
443 type IterNames = iter::IterNames<Self>;
444}
445
446impl<B: Flags> ImplementedByBitFlagsMacro for B {}
447
448#[doc(hidden)]
453pub trait ImplementedByBitFlagsMacro {}
454
455pub(crate) mod __private {
456 pub use super::{ImplementedByBitFlagsMacro, PublicFlags};
457}