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