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                    let mut truncated = <$T as $crate::Bits>::EMPTY;
152                    let mut i = 0;
153
154                    $(
155                        $crate::__bitflags_expr_safe_attrs!(
156                            $(#[$inner $($args)*])*
157                            {{
158                                let flag = <$PublicBitFlags as $crate::Flags>::FLAGS[i].value().bits();
159
160                                truncated = truncated | flag;
161                                i += 1;
162                            }}
163                        );
164                    )*
165
166                    let _ = i;
167                    Self(truncated)
168                }
169
170                fn bits(&self) {
171                    self.0
172                }
173
174                fn from_bits(bits) {
175                    let truncated = Self::from_bits_truncate(bits).0;
176
177                    if truncated == bits {
178                        $crate::__private::core::option::Option::Some(Self(bits))
179                    } else {
180                        $crate::__private::core::option::Option::None
181                    }
182                }
183
184                fn from_bits_truncate(bits) {
185                    Self(bits & Self::all().0)
186                }
187
188                fn from_bits_retain(bits) {
189                    Self(bits)
190                }
191
192                fn from_name(name) {
193                    $(
194                        $crate::__bitflags_flag!({
195                            name: $Flag,
196                            named: {
197                                $crate::__bitflags_expr_safe_attrs!(
198                                    $(#[$inner $($args)*])*
199                                    {
200                                        if name == $crate::__private::core::stringify!($Flag) {
201                                            return $crate::__private::core::option::Option::Some(Self($PublicBitFlags::$Flag.bits()));
202                                        }
203                                    }
204                                );
205                            },
206                            unnamed: {},
207                        });
208                    )*
209
210                    let _ = name;
211                    $crate::__private::core::option::Option::None
212                }
213
214                fn is_empty(&self) {
215                    self.0 == <$T as $crate::Bits>::EMPTY
216                }
217
218                fn is_all(&self) {
219                    // NOTE: We check against `Self::all` here, not `Self::Bits::ALL`
220                    // because the set of all flags may not use all bits
221                    Self::all().0 | self.0 == self.0
222                }
223
224                fn intersects(&self, other) {
225                    self.0 & other.0 != <$T as $crate::Bits>::EMPTY
226                }
227
228                fn contains(&self, other) {
229                    self.0 & other.0 == other.0
230                }
231
232                fn insert(&mut self, other) {
233                    *self = Self(self.0).union(other);
234                }
235
236                fn remove(&mut self, other) {
237                    *self = Self(self.0).difference(other);
238                }
239
240                fn toggle(&mut self, other) {
241                    *self = Self(self.0).symmetric_difference(other);
242                }
243
244                fn set(&mut self, other, value) {
245                    if value {
246                        self.insert(other);
247                    } else {
248                        self.remove(other);
249                    }
250                }
251
252                fn intersection(self, other) {
253                    Self(self.0 & other.0)
254                }
255
256                fn union(self, other) {
257                    Self(self.0 | other.0)
258                }
259
260                fn difference(self, other) {
261                    Self(self.0 & !other.0)
262                }
263
264                fn symmetric_difference(self, other) {
265                    Self(self.0 ^ other.0)
266                }
267
268                fn complement(self) {
269                    Self::from_bits_truncate(!self.0)
270                }
271            }
272        }
273    };
274}
275
276/// Implement iterators on the public (user-facing) bitflags type.
277#[macro_export]
278#[doc(hidden)]
279macro_rules! __impl_public_bitflags_iter {
280    (
281        $(#[$outer:meta])*
282        $BitFlags:ident: $T:ty, $PublicBitFlags:ident
283    ) => {
284        $(#[$outer])*
285        impl $BitFlags {
286            /// Yield a set of contained flags values.
287            ///
288            /// Each yielded flags value will correspond to a defined named flag. Any unknown bits
289            /// will be yielded together as a final flags value.
290            #[inline]
291            pub const fn iter(&self) -> $crate::iter::Iter<$PublicBitFlags> {
292                $crate::iter::Iter::__private_const_new(
293                    <$PublicBitFlags as $crate::Flags>::FLAGS,
294                    $PublicBitFlags::from_bits_retain(self.bits()),
295                    $PublicBitFlags::from_bits_retain(self.bits()),
296                )
297            }
298
299            /// Yield a set of contained named flags values.
300            ///
301            /// This method is like [`iter`](#method.iter), except only yields bits in contained named flags.
302            /// Any unknown bits, or bits not corresponding to a contained flag will not be yielded.
303            #[inline]
304            pub const fn iter_names(&self) -> $crate::iter::IterNames<$PublicBitFlags> {
305                $crate::iter::IterNames::__private_const_new(
306                    <$PublicBitFlags as $crate::Flags>::FLAGS,
307                    $PublicBitFlags::from_bits_retain(self.bits()),
308                    $PublicBitFlags::from_bits_retain(self.bits()),
309                )
310            }
311        }
312
313        $(#[$outer:meta])*
314        impl $crate::__private::core::iter::IntoIterator for $BitFlags {
315            type Item = $PublicBitFlags;
316            type IntoIter = $crate::iter::Iter<$PublicBitFlags>;
317
318            fn into_iter(self) -> Self::IntoIter {
319                self.iter()
320            }
321        }
322    };
323}
324
325/// Implement traits on the public (user-facing) bitflags type.
326#[macro_export]
327#[doc(hidden)]
328macro_rules! __impl_public_bitflags_ops {
329    (
330        $(#[$outer:meta])*
331        $PublicBitFlags:ident
332    ) => {
333
334        $(#[$outer])*
335        impl $crate::__private::core::fmt::Binary for $PublicBitFlags {
336            fn fmt(
337                &self,
338                f: &mut $crate::__private::core::fmt::Formatter,
339            ) -> $crate::__private::core::fmt::Result {
340                let inner = self.0;
341                $crate::__private::core::fmt::Binary::fmt(&inner, f)
342            }
343        }
344
345        $(#[$outer])*
346        impl $crate::__private::core::fmt::Octal for $PublicBitFlags {
347            fn fmt(
348                &self,
349                f: &mut $crate::__private::core::fmt::Formatter,
350            ) -> $crate::__private::core::fmt::Result {
351                let inner = self.0;
352                $crate::__private::core::fmt::Octal::fmt(&inner, f)
353            }
354        }
355
356        $(#[$outer])*
357        impl $crate::__private::core::fmt::LowerHex for $PublicBitFlags {
358            fn fmt(
359                &self,
360                f: &mut $crate::__private::core::fmt::Formatter,
361            ) -> $crate::__private::core::fmt::Result {
362                let inner = self.0;
363                $crate::__private::core::fmt::LowerHex::fmt(&inner, f)
364            }
365        }
366
367        $(#[$outer])*
368        impl $crate::__private::core::fmt::UpperHex for $PublicBitFlags {
369            fn fmt(
370                &self,
371                f: &mut $crate::__private::core::fmt::Formatter,
372            ) -> $crate::__private::core::fmt::Result {
373                let inner = self.0;
374                $crate::__private::core::fmt::UpperHex::fmt(&inner, f)
375            }
376        }
377
378        $(#[$outer])*
379        impl $crate::__private::core::ops::BitOr for $PublicBitFlags {
380            type Output = Self;
381
382            /// The bitwise or (`|`) of the bits in two flags values.
383            #[inline]
384            fn bitor(self, other: $PublicBitFlags) -> Self {
385                self.union(other)
386            }
387        }
388
389        $(#[$outer])*
390        impl $crate::__private::core::ops::BitOrAssign for $PublicBitFlags {
391            /// The bitwise or (`|`) of the bits in two flags values.
392            #[inline]
393            fn bitor_assign(&mut self, other: Self) {
394                self.insert(other);
395            }
396        }
397
398        $(#[$outer])*
399        impl $crate::__private::core::ops::BitXor for $PublicBitFlags {
400            type Output = Self;
401
402            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
403            #[inline]
404            fn bitxor(self, other: Self) -> Self {
405                self.symmetric_difference(other)
406            }
407        }
408
409        $(#[$outer])*
410        impl $crate::__private::core::ops::BitXorAssign for $PublicBitFlags {
411            /// The bitwise exclusive-or (`^`) of the bits in two flags values.
412            #[inline]
413            fn bitxor_assign(&mut self, other: Self) {
414                self.toggle(other);
415            }
416        }
417
418        $(#[$outer])*
419        impl $crate::__private::core::ops::BitAnd for $PublicBitFlags {
420            type Output = Self;
421
422            /// The bitwise and (`&`) of the bits in two flags values.
423            #[inline]
424            fn bitand(self, other: Self) -> Self {
425                self.intersection(other)
426            }
427        }
428
429        $(#[$outer])*
430        impl $crate::__private::core::ops::BitAndAssign for $PublicBitFlags {
431            /// The bitwise and (`&`) of the bits in two flags values.
432            #[inline]
433            fn bitand_assign(&mut self, other: Self) {
434                *self = Self::from_bits_retain(self.bits()).intersection(other);
435            }
436        }
437
438        $(#[$outer])*
439        impl $crate::__private::core::ops::Sub for $PublicBitFlags {
440            type Output = Self;
441
442            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
443            ///
444            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
445            /// `difference` won't truncate `other`, but the `!` operator will.
446            #[inline]
447            fn sub(self, other: Self) -> Self {
448                self.difference(other)
449            }
450        }
451
452        $(#[$outer])*
453        impl $crate::__private::core::ops::SubAssign for $PublicBitFlags {
454            /// The intersection of a source flags value with the complement of a target flags value (`&!`).
455            ///
456            /// This method is not equivalent to `self & !other` when `other` has unknown bits set.
457            /// `difference` won't truncate `other`, but the `!` operator will.
458            #[inline]
459            fn sub_assign(&mut self, other: Self) {
460                self.remove(other);
461            }
462        }
463
464        $(#[$outer])*
465        impl $crate::__private::core::ops::Not for $PublicBitFlags {
466            type Output = Self;
467
468            /// The bitwise negation (`!`) of the bits in a flags value, truncating the result.
469            #[inline]
470            fn not(self) -> Self {
471                self.complement()
472            }
473        }
474
475        $(#[$outer])*
476        impl $crate::__private::core::iter::Extend<$PublicBitFlags> for $PublicBitFlags {
477            /// The bitwise or (`|`) of the bits in each flags value.
478            fn extend<T: $crate::__private::core::iter::IntoIterator<Item = Self>>(
479                &mut self,
480                iterator: T,
481            ) {
482                for item in iterator {
483                    self.insert(item)
484                }
485            }
486        }
487
488        $(#[$outer])*
489        impl $crate::__private::core::iter::FromIterator<$PublicBitFlags> for $PublicBitFlags {
490            /// The bitwise or (`|`) of the bits in each flags value.
491            fn from_iter<T: $crate::__private::core::iter::IntoIterator<Item = Self>>(
492                iterator: T,
493            ) -> Self {
494                use $crate::__private::core::iter::Extend;
495
496                let mut result = Self::empty();
497                result.extend(iterator);
498                result
499            }
500        }
501    };
502}
503
504/// Implement constants on the public (user-facing) bitflags type.
505#[macro_export]
506#[doc(hidden)]
507macro_rules! __impl_public_bitflags_consts {
508    (
509        $(#[$outer:meta])*
510        $PublicBitFlags:ident: $T:ty {
511            $(
512                $(#[$inner:ident $($args:tt)*])*
513                const $Flag:tt = $value:expr;
514            )*
515        }
516    ) => {
517        $(#[$outer])*
518        impl $PublicBitFlags {
519            $(
520                $crate::__bitflags_flag!({
521                    name: $Flag,
522                    named: {
523                        $(#[$inner $($args)*])*
524                        #[allow(
525                            deprecated,
526                            non_upper_case_globals,
527                        )]
528                        pub const $Flag: Self = Self::from_bits_retain($value);
529                    },
530                    unnamed: {},
531                });
532            )*
533        }
534
535        $(#[$outer])*
536        impl $crate::Flags for $PublicBitFlags {
537            const FLAGS: &'static [$crate::Flag<$PublicBitFlags>] = &[
538                $(
539                    $crate::__bitflags_flag!({
540                        name: $Flag,
541                        named: {
542                            $crate::__bitflags_expr_safe_attrs!(
543                                $(#[$inner $($args)*])*
544                                {
545                                    #[allow(
546                                        deprecated,
547                                        non_upper_case_globals,
548                                    )]
549                                    $crate::Flag::new($crate::__private::core::stringify!($Flag), $PublicBitFlags::$Flag)
550                                }
551                            )
552                        },
553                        unnamed: {
554                            $crate::__bitflags_expr_safe_attrs!(
555                                $(#[$inner $($args)*])*
556                                {
557                                    #[allow(
558                                        deprecated,
559                                        non_upper_case_globals,
560                                    )]
561                                    $crate::Flag::new("", $PublicBitFlags::from_bits_retain($value))
562                                }
563                            )
564                        },
565                    }),
566                )*
567            ];
568
569            type Bits = $T;
570
571            fn bits(&self) -> $T {
572                $PublicBitFlags::bits(self)
573            }
574
575            fn from_bits_retain(bits: $T) -> $PublicBitFlags {
576                $PublicBitFlags::from_bits_retain(bits)
577            }
578        }
579    };
580}