Skip to main content

bitflags/
public.rs

1//! Generate the user-facing flags type.
2//!
3//! The code here belongs to the end-user, so new trait implementations and methods can't be
4//! added without potentially breaking users.
5
6/// Declare the user-facing bitflags struct.
7///
8/// This type is guaranteed to be a newtype with a `bitflags`-facing type as its single field.
9#[macro_export]
10#[doc(hidden)]
11macro_rules! __declare_public_bitflags {
12    (
13        $(#[$outer:meta])*
14        $vis:vis struct $PublicBitFlags:ident
15    ) => {
16        $(#[$outer])*
17        $vis struct $PublicBitFlags(<$PublicBitFlags as $crate::__private::PublicFlags>::Internal);
18    };
19}
20
21/// Implement functions on the public (user-facing) bitflags type.
22///
23/// We need to be careful about adding new methods and trait implementations here because they
24/// could conflict with items added by the end-user.
25#[macro_export]
26#[doc(hidden)]
27macro_rules! __impl_public_bitflags_forward {
28    (
29        $(#[$outer:meta])*
30        $PublicBitFlags:ident: $T:ty, $InternalBitFlags:ident
31    ) => {
32        $crate::__impl_bitflags! {
33            params: self, bits, name, other, value;
34            $(#[$outer])*
35            $PublicBitFlags: $T {
36                fn empty() {
37                    Self($InternalBitFlags::empty())
38                }
39
40                fn all() {
41                    Self($InternalBitFlags::all())
42                }
43
44                fn bits(&self) {
45                    self.0.bits()
46                }
47
48                fn from_bits(bits) {
49                    match $InternalBitFlags::from_bits(bits) {
50                        $crate::__private::core::option::Option::Some(bits) => $crate::__private::core::option::Option::Some(Self(bits)),
51                        $crate::__private::core::option::Option::None => $crate::__private::core::option::Option::None,
52                    }
53                }
54
55                fn from_bits_truncate(bits) {
56                    Self($InternalBitFlags::from_bits_truncate(bits))
57                }
58
59                fn from_bits_retain(bits) {
60                    Self($InternalBitFlags::from_bits_retain(bits))
61                }
62
63                fn from_name(name) {
64                    match $InternalBitFlags::from_name(name) {
65                        $crate::__private::core::option::Option::Some(bits) => $crate::__private::core::option::Option::Some(Self(bits)),
66                        $crate::__private::core::option::Option::None => $crate::__private::core::option::Option::None,
67                    }
68                }
69
70                fn is_empty(&self) {
71                    self.0.is_empty()
72                }
73
74                fn is_all(&self) {
75                    self.0.is_all()
76                }
77
78                fn intersects(&self, other) {
79                    self.0.intersects(other.0)
80                }
81
82                fn contains(&self, other) {
83                    self.0.contains(other.0)
84                }
85
86                fn insert(&mut self, other) {
87                    self.0.insert(other.0)
88                }
89
90                fn remove(&mut self, other) {
91                    self.0.remove(other.0)
92                }
93
94                fn toggle(&mut self, other) {
95                    self.0.toggle(other.0)
96                }
97
98                fn set(&mut self, other, value) {
99                    self.0.set(other.0, value)
100                }
101
102                fn intersection(self, other) {
103                    Self(self.0.intersection(other.0))
104                }
105
106                fn union(self, other) {
107                    Self(self.0.union(other.0))
108                }
109
110                fn difference(self, other) {
111                    Self(self.0.difference(other.0))
112                }
113
114                fn symmetric_difference(self, other) {
115                    Self(self.0.symmetric_difference(other.0))
116                }
117
118                fn complement(self) {
119                    Self(self.0.complement())
120                }
121            }
122        }
123    };
124}
125
126/// Implement functions on the public (user-facing) bitflags type.
127///
128/// We need to be careful about adding new methods and trait implementations here because they
129/// could conflict with items added by the end-user.
130#[macro_export]
131#[doc(hidden)]
132macro_rules! __impl_public_bitflags {
133    (
134        $(#[$outer:meta])*
135        $BitFlags:ident: $T:ty, $PublicBitFlags:ident {
136            $(
137                $(#[$inner:ident $($args:tt)*])*
138                const $Flag:tt = $value:expr;
139            )*
140        }
141    ) => {
142        $crate::__impl_bitflags! {
143            params: self, bits, name, other, value;
144            $(#[$outer])*
145            $BitFlags: $T {
146                fn empty() {
147                    Self(<$T as $crate::Bits>::EMPTY)
148                }
149
150                fn all() {
151                    const ALL: $BitFlags = {
152                        let mut truncated = <$T as $crate::Bits>::EMPTY;
153                        let mut _i = 0;
154
155                        $(
156                            $crate::__bitflags_expr_safe_attrs!(
157                                $(#[$inner $($args)*])*
158                                {{
159                                    truncated |= <$PublicBitFlags as $crate::Flags>::FLAGS[_i]
160                                        .value().bits();
161                                    _i += 1;
162                                }}
163                            );
164                        )*
165
166                        $BitFlags(truncated)
167                    };
168
169                    ALL
170                }
171
172                fn bits(&self) {
173                    self.0
174                }
175
176                fn from_bits(bits) {
177                    let truncated = Self::from_bits_truncate(bits).0;
178
179                    if truncated == bits {
180                        $crate::__private::core::option::Option::Some(Self(bits))
181                    } else {
182                        $crate::__private::core::option::Option::None
183                    }
184                }
185
186                fn from_bits_truncate(bits) {
187                    Self(bits & Self::all().0)
188                }
189
190                fn from_bits_retain(bits) {
191                    Self(bits)
192                }
193
194                fn from_name(name) {
195                    mod __bitflags_flag_names {
196                        #[allow(unused_imports)]
197                        use super::*;
198
199                        $(
200                            $crate::__bitflags_flag_name!(
201                                $(#[$inner $($args)*])*
202                                { pub(super) const $Flag = $Flag }
203                            );
204                        )*
205                    }
206
207                    $(
208                        $crate::__bitflags_flag!({
209                            name: $Flag,
210                            named: {{
211                                $crate::__bitflags_expr_safe_attrs!(
212                                    $(#[$inner $($args)*])*
213                                    {
214                                        if name == __bitflags_flag_names::$Flag {
215                                            return $crate::__private::core::option::Option::Some(Self($PublicBitFlags::$Flag.bits()));
216                                        }
217                                    }
218                                );
219                            }},
220                            unnamed: {},
221                        });
222                    )*
223
224                    let _ = name;
225                    $crate::__private::core::option::Option::None
226                }
227
228                fn is_empty(&self) {
229                    self.0 == <$T as $crate::Bits>::EMPTY
230                }
231
232                fn is_all(&self) {
233                    // NOTE: We check against `Self::all` here, not `Self::Bits::ALL`
234                    // because the set of all flags may not use all bits
235                    Self::all().0 | self.0 == self.0
236                }
237
238                fn intersects(&self, other) {
239                    self.0 & other.0 != <$T as $crate::Bits>::EMPTY
240                }
241
242                fn contains(&self, other) {
243                    self.0 & other.0 == other.0
244                }
245
246                fn insert(&mut self, other) {
247                    *self = Self(self.0).union(other);
248                }
249
250                fn remove(&mut self, other) {
251                    *self = Self(self.0).difference(other);
252                }
253
254                fn toggle(&mut self, other) {
255                    *self = Self(self.0).symmetric_difference(other);
256                }
257
258                fn set(&mut self, other, value) {
259                    if value {
260                        self.insert(other);
261                    } else {
262                        self.remove(other);
263                    }
264                }
265
266                fn intersection(self, other) {
267                    Self(self.0 & other.0)
268                }
269
270                fn union(self, other) {
271                    Self(self.0 | other.0)
272                }
273
274                fn difference(self, other) {
275                    Self(self.0 & !other.0)
276                }
277
278                fn symmetric_difference(self, other) {
279                    Self(self.0 ^ other.0)
280                }
281
282                fn complement(self) {
283                    Self::from_bits_truncate(!self.0)
284                }
285            }
286        }
287    };
288}
289
290/// Implement iterators on the public (user-facing) bitflags type.
291#[macro_export]
292#[doc(hidden)]
293macro_rules! __impl_public_bitflags_iter {
294    (
295        $(#[$outer:meta])*
296        $BitFlags:ident: $T:ty, $PublicBitFlags:ident
297    ) => {
298        $(#[$outer])*
299        impl $BitFlags {
300            /// Yield a set of contained flags values.
301            ///
302            /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
303            /// will be yielded together as a final flags value.
304            #[inline]
305            pub const fn iter(&self) -> $crate::iter::Iter<$PublicBitFlags> {
306                $crate::iter::Iter::__private_const_new(
307                    <$PublicBitFlags as $crate::Flags>::FLAGS,
308                    $PublicBitFlags::from_bits_retain(self.bits()),
309                    $PublicBitFlags::from_bits_retain(self.bits()),
310                )
311            }
312
313            /// Yield a set of contained named flags values.
314            ///
315            /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags.
316            /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
317            #[inline]
318            pub const fn iter_names(&self) -> $crate::iter::IterNames<$PublicBitFlags> {
319                $crate::iter::IterNames::__private_const_new(
320                    <$PublicBitFlags as $crate::Flags>::FLAGS,
321                    $PublicBitFlags::from_bits_retain(self.bits()),
322                    $PublicBitFlags::from_bits_retain(self.bits()),
323                )
324            }
325        }
326
327        $(#[$outer:meta])*
328        impl $crate::__private::core::iter::IntoIterator for $BitFlags {
329            type Item = $PublicBitFlags;
330            type IntoIter = $crate::iter::Iter<$PublicBitFlags>;
331
332            fn into_iter(self) -> Self::IntoIter {
333                self.iter()
334            }
335        }
336    };
337}
338
339/// Implement traits on the public (user-facing) bitflags type.
340#[macro_export]
341#[doc(hidden)]
342macro_rules! __impl_public_bitflags_ops {
343    (
344        $(#[$outer:meta])*
345        $PublicBitFlags:ident
346    ) => {
347
348        $(#[$outer])*
349        impl $crate::__private::core::fmt::Binary for $PublicBitFlags {
350            fn fmt(
351                &self,
352                f: &mut $crate::__private::core::fmt::Formatter,
353            ) -> $crate::__private::core::fmt::Result {
354                let inner = self.0;
355                $crate::__private::core::fmt::Binary::fmt(&inner, f)
356            }
357        }
358
359        $(#[$outer])*
360        impl $crate::__private::core::fmt::Octal for $PublicBitFlags {
361            fn fmt(
362                &self,
363                f: &mut $crate::__private::core::fmt::Formatter,
364            ) -> $crate::__private::core::fmt::Result {
365                let inner = self.0;
366                $crate::__private::core::fmt::Octal::fmt(&inner, f)
367            }
368        }
369
370        $(#[$outer])*
371        impl $crate::__private::core::fmt::LowerHex for $PublicBitFlags {
372            fn fmt(
373                &self,
374                f: &mut $crate::__private::core::fmt::Formatter,
375            ) -> $crate::__private::core::fmt::Result {
376                let inner = self.0;
377                $crate::__private::core::fmt::LowerHex::fmt(&inner, f)
378            }
379        }
380
381        $(#[$outer])*
382        impl $crate::__private::core::fmt::UpperHex for $PublicBitFlags {
383            fn fmt(
384                &self,
385                f: &mut $crate::__private::core::fmt::Formatter,
386            ) -> $crate::__private::core::fmt::Result {
387                let inner = self.0;
388                $crate::__private::core::fmt::UpperHex::fmt(&inner, f)
389            }
390        }
391
392        $(#[$outer])*
393        impl $crate::__private::core::ops::BitOr for $PublicBitFlags {
394            type Output = Self;
395
396            /// The bitwise or (`|`) of the bits in `self` and `other`.
397            #[inline]
398            fn bitor(self, other: $PublicBitFlags) -> Self {
399                self.union(other)
400            }
401        }
402
403        $(#[$outer])*
404        impl $crate::__private::core::ops::BitOrAssign for $PublicBitFlags {
405            /// The bitwise or (`|`) of the bits in `self` and `other`.
406            #[inline]
407            fn bitor_assign(&mut self, other: Self) {
408                self.insert(other);
409            }
410        }
411
412        $(#[$outer])*
413        impl $crate::__private::core::ops::BitXor for $PublicBitFlags {
414            type Output = Self;
415
416            /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.
417            #[inline]
418            fn bitxor(self, other: Self) -> Self {
419                self.symmetric_difference(other)
420            }
421        }
422
423        $(#[$outer])*
424        impl $crate::__private::core::ops::BitXorAssign for $PublicBitFlags {
425            /// The bitwise exclusive-or (`^`) of the bits in `self` and `other`.
426            #[inline]
427            fn bitxor_assign(&mut self, other: Self) {
428                self.toggle(other);
429            }
430        }
431
432        $(#[$outer])*
433        impl $crate::__private::core::ops::BitAnd for $PublicBitFlags {
434            type Output = Self;
435
436            /// The bitwise and (`&`) of the bits in `self` and `other`.
437            #[inline]
438            fn bitand(self, other: Self) -> Self {
439                self.intersection(other)
440            }
441        }
442
443        $(#[$outer])*
444        impl $crate::__private::core::ops::BitAndAssign for $PublicBitFlags {
445            /// The bitwise and (`&`) of the bits in `self` and `other`.
446            #[inline]
447            fn bitand_assign(&mut self, other: Self) {
448                *self = Self::from_bits_retain(self.bits()).intersection(other);
449            }
450        }
451
452        $(#[$outer])*
453        impl $crate::__private::core::ops::Sub for $PublicBitFlags {
454            type Output = Self;
455
456            /// The intersection of `self` with the complement of `other` (`&!`).
457            ///
458            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
459            /// `difference` won't truncate `other`, but the `!` operator will.
460            #[inline]
461            fn sub(self, other: Self) -> Self {
462                self.difference(other)
463            }
464        }
465
466        $(#[$outer])*
467        impl $crate::__private::core::ops::SubAssign for $PublicBitFlags {
468            /// The intersection of `self` with the complement of `other` (`&!`).
469            ///
470            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
471            /// `difference` won't truncate `other`, but the `!` operator will.
472            #[inline]
473            fn sub_assign(&mut self, other: Self) {
474                self.remove(other);
475            }
476        }
477
478        $(#[$outer])*
479        impl $crate::__private::core::ops::Not for $PublicBitFlags {
480            type Output = Self;
481
482            /// The bitwise negation (`!`) of the bits in `self`, truncating the result.
483            #[inline]
484            fn not(self) -> Self {
485                self.complement()
486            }
487        }
488
489        $(#[$outer])*
490        impl $crate::__private::core::iter::Extend<$PublicBitFlags> for $PublicBitFlags {
491            /// The bitwise or (`|`) of the bits in each flags value.
492            fn extend<T: $crate::__private::core::iter::IntoIterator<Item = Self>>(
493                &mut self,
494                iterator: T,
495            ) {
496                for item in iterator {
497                    self.insert(item)
498                }
499            }
500        }
501
502        $(#[$outer])*
503        impl $crate::__private::core::iter::FromIterator<$PublicBitFlags> for $PublicBitFlags {
504            /// The bitwise or (`|`) of the bits in each flags value.
505            fn from_iter<T: $crate::__private::core::iter::IntoIterator<Item = Self>>(
506                iterator: T,
507            ) -> Self {
508                use $crate::__private::core::iter::Extend;
509
510                let mut result = Self::empty();
511                result.extend(iterator);
512                result
513            }
514        }
515    };
516}
517
518/// Implement constants on the public (user-facing) bitflags type.
519#[macro_export]
520#[doc(hidden)]
521macro_rules! __impl_public_bitflags_consts {
522    (
523        $(#[$outer:meta])*
524        $PublicBitFlags:ident: $T:ty {
525            $(
526                $(#[$inner:ident $($args:tt)*])*
527                const $Flag:tt = $value:expr;
528            )*
529        }
530    ) => {
531        $(#[$outer])*
532        impl $PublicBitFlags {
533            $(
534                $crate::__bitflags_flag!({
535                    name: $Flag,
536                    named: {
537                        $crate::__bitflags_item_safe_attrs!(
538                            $(#[$inner $($args)*])*
539                            {
540                                pub const $Flag: Self = Self::from_bits_retain($value);
541                            }
542                        );
543                    },
544                    unnamed: {},
545                });
546            )*
547        }
548
549        $(#[$outer])*
550        impl $crate::Flags for $PublicBitFlags {
551            const FLAGS: &'static [$crate::Flag<$PublicBitFlags>] = {
552                mod __bitflags_flag_names {
553                    #[allow(unused_imports)]
554                    use super::*;
555
556                    $(
557                        $crate::__bitflags_flag_name!(
558                            $(#[$inner $($args)*])*
559                            { pub(super) const $Flag = $Flag });
560                    )*
561                }
562
563                &[
564                    $(
565                        $crate::__bitflags_flag!({
566                            name: $Flag,
567                            named: {
568                                $crate::__bitflags_expr_safe_attrs!(
569                                    $(#[$inner $($args)*])*
570                                    {
571                                        $crate::Flag::new(__bitflags_flag_names::$Flag, $PublicBitFlags::$Flag)
572                                    }
573                                )
574                            },
575                            unnamed: {
576                                $crate::__bitflags_expr_safe_attrs!(
577                                    $(#[$inner $($args)*])*
578                                    {
579                                        $crate::Flag::new("", $PublicBitFlags::from_bits_retain($value))
580                                    }
581                                )
582                            },
583                        }),
584                    )*
585                ]
586            };
587
588            type Bits = $T;
589
590            fn bits(&self) -> $T {
591                $PublicBitFlags::bits(self)
592            }
593
594            fn from_bits_retain(bits: $T) -> $PublicBitFlags {
595                $PublicBitFlags::from_bits_retain(bits)
596            }
597
598            fn all_named() -> $PublicBitFlags {
599                const ALL_NAMED: $T = {
600                    let mut truncated = <$T as $crate::Bits>::EMPTY;
601                    let mut i = 0;
602
603                    $(
604                        $crate::__bitflags_expr_safe_attrs!(
605                            $(#[$inner $($args)*])*
606                            {{
607                                let flag = &<$PublicBitFlags as $crate::Flags>::FLAGS[i];
608
609                                if flag.is_named() {
610                                    truncated = truncated | flag.value().bits();
611                                }
612
613                                i += 1;
614                            }}
615                        );
616                    )*
617
618                    let _ = i;
619                    truncated
620                };
621
622                $PublicBitFlags::from_bits_retain(ALL_NAMED)
623            }
624        }
625    };
626}