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