Coverage Report

Created: 2025-07-23 06:46

/rust/registry/src/index.crates.io-6f17d22bba15001f/bitflags-2.9.1/src/iter.rs
Line
Count
Source (jump to first uncovered line)
1
/*!
2
Yield the bits of a source flags value in a set of contained flags values.
3
*/
4
5
use crate::{Flag, Flags};
6
7
/**
8
An iterator over flags values.
9
10
This iterator will yield flags values for contained, defined flags first, with any remaining bits yielded
11
as a final flags value.
12
*/
13
pub struct Iter<B: 'static> {
14
    inner: IterNames<B>,
15
    done: bool,
16
}
17
18
impl<B: Flags> Iter<B> {
19
0
    pub(crate) fn new(flags: &B) -> Self {
20
0
        Iter {
21
0
            inner: IterNames::new(flags),
22
0
            done: false,
23
0
        }
24
0
    }
25
}
26
27
impl<B: 'static> Iter<B> {
28
    // Used by the `bitflags` macro
29
    #[doc(hidden)]
30
0
    pub const fn __private_const_new(flags: &'static [Flag<B>], source: B, remaining: B) -> Self {
31
0
        Iter {
32
0
            inner: IterNames::__private_const_new(flags, source, remaining),
33
0
            done: false,
34
0
        }
35
0
    }
Unexecuted instantiation: <bitflags::iter::Iter<webpsan::parse::alph::AlphFlags>>::__private_const_new
Unexecuted instantiation: <bitflags::iter::Iter<webpsan::parse::anmf::AnmfFlags>>::__private_const_new
Unexecuted instantiation: <bitflags::iter::Iter<webpsan::parse::vp8x::Vp8xFlags>>::__private_const_new
Unexecuted instantiation: <bitflags::iter::Iter<_>>::__private_const_new
36
}
37
38
impl<B: Flags> Iterator for Iter<B> {
39
    type Item = B;
40
41
0
    fn next(&mut self) -> Option<Self::Item> {
42
0
        match self.inner.next() {
43
0
            Some((_, flag)) => Some(flag),
44
0
            None if !self.done => {
45
0
                self.done = true;
46
0
47
0
                // After iterating through valid names, if there are any bits left over
48
0
                // then return one final value that includes them. This makes `into_iter`
49
0
                // and `from_iter` roundtrip
50
0
                if !self.inner.remaining().is_empty() {
51
0
                    Some(B::from_bits_retain(self.inner.remaining.bits()))
52
                } else {
53
0
                    None
54
                }
55
            }
56
0
            None => None,
57
        }
58
0
    }
59
}
60
61
/**
62
An iterator over flags values.
63
64
This iterator only yields flags values for contained, defined, named flags. Any remaining bits
65
won't be yielded, but can be found with the [`IterNames::remaining`] method.
66
*/
67
pub struct IterNames<B: 'static> {
68
    flags: &'static [Flag<B>],
69
    idx: usize,
70
    source: B,
71
    remaining: B,
72
}
73
74
impl<B: Flags> IterNames<B> {
75
0
    pub(crate) fn new(flags: &B) -> Self {
76
0
        IterNames {
77
0
            flags: B::FLAGS,
78
0
            idx: 0,
79
0
            remaining: B::from_bits_retain(flags.bits()),
80
0
            source: B::from_bits_retain(flags.bits()),
81
0
        }
82
0
    }
Unexecuted instantiation: <bitflags::iter::IterNames<webpsan::parse::alph::AlphFlags>>::new
Unexecuted instantiation: <bitflags::iter::IterNames<webpsan::parse::anmf::AnmfFlags>>::new
Unexecuted instantiation: <bitflags::iter::IterNames<webpsan::parse::vp8x::Vp8xFlags>>::new
Unexecuted instantiation: <bitflags::iter::IterNames<_>>::new
83
}
84
85
impl<B: 'static> IterNames<B> {
86
    // Used by the bitflags macro
87
    #[doc(hidden)]
88
0
    pub const fn __private_const_new(flags: &'static [Flag<B>], source: B, remaining: B) -> Self {
89
0
        IterNames {
90
0
            flags,
91
0
            idx: 0,
92
0
            remaining,
93
0
            source,
94
0
        }
95
0
    }
Unexecuted instantiation: <bitflags::iter::IterNames<webpsan::parse::alph::AlphFlags>>::__private_const_new
Unexecuted instantiation: <bitflags::iter::IterNames<webpsan::parse::anmf::AnmfFlags>>::__private_const_new
Unexecuted instantiation: <bitflags::iter::IterNames<webpsan::parse::vp8x::Vp8xFlags>>::__private_const_new
Unexecuted instantiation: <bitflags::iter::IterNames<_>>::__private_const_new
96
97
    /// Get a flags value of any remaining bits that haven't been yielded yet.
98
    ///
99
    /// Once the iterator has finished, this method can be used to
100
    /// check whether or not there are any bits that didn't correspond
101
    /// to a contained, defined, named flag remaining.
102
0
    pub fn remaining(&self) -> &B {
103
0
        &self.remaining
104
0
    }
Unexecuted instantiation: <bitflags::iter::IterNames<webpsan::parse::alph::AlphFlags>>::remaining
Unexecuted instantiation: <bitflags::iter::IterNames<webpsan::parse::anmf::AnmfFlags>>::remaining
Unexecuted instantiation: <bitflags::iter::IterNames<webpsan::parse::vp8x::Vp8xFlags>>::remaining
Unexecuted instantiation: <bitflags::iter::IterNames<_>>::remaining
105
}
106
107
impl<B: Flags> Iterator for IterNames<B> {
108
    type Item = (&'static str, B);
109
110
0
    fn next(&mut self) -> Option<Self::Item> {
111
0
        while let Some(flag) = self.flags.get(self.idx) {
112
            // Short-circuit if our state is empty
113
0
            if self.remaining.is_empty() {
114
0
                return None;
115
0
            }
116
0
117
0
            self.idx += 1;
118
0
119
0
            // Skip unnamed flags
120
0
            if flag.name().is_empty() {
121
0
                continue;
122
0
            }
123
0
124
0
            let bits = flag.value().bits();
125
0
126
0
            // If the flag is set in the original source _and_ it has bits that haven't
127
0
            // been covered by a previous flag yet then yield it. These conditions cover
128
0
            // two cases for multi-bit flags:
129
0
            //
130
0
            // 1. When flags partially overlap, such as `0b00000001` and `0b00000101`, we'll
131
0
            // yield both flags.
132
0
            // 2. When flags fully overlap, such as in convenience flags that are a shorthand for others,
133
0
            // we won't yield both flags.
134
0
            if self.source.contains(B::from_bits_retain(bits))
135
0
                && self.remaining.intersects(B::from_bits_retain(bits))
136
            {
137
0
                self.remaining.remove(B::from_bits_retain(bits));
138
0
139
0
                return Some((flag.name(), B::from_bits_retain(bits)));
140
0
            }
141
        }
142
143
0
        None
144
0
    }
Unexecuted instantiation: <bitflags::iter::IterNames<webpsan::parse::alph::AlphFlags> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <bitflags::iter::IterNames<webpsan::parse::anmf::AnmfFlags> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <bitflags::iter::IterNames<webpsan::parse::vp8x::Vp8xFlags> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <bitflags::iter::IterNames<_> as core::iter::traits::iterator::Iterator>::next
145
}