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