1use crate::{Flag, Flags};
6
7pub struct Iter<B: 'static> {
14 inner: IterNames<B>,
15 done: bool,
16}
17
18impl<B: Flags> Iter<B> {
19 pub(crate) fn new(flags: &B) -> Self {
20 Iter {
21 inner: IterNames::new(flags),
22 done: false,
23 }
24 }
25}
26
27impl<B: 'static> Iter<B> {
28 #[doc(hidden)]
30 pub const fn __private_const_new(flags: &'static [Flag<B>], source: B, remaining: B) -> Self {
31 Iter {
32 inner: IterNames::__private_const_new(flags, source, remaining),
33 done: false,
34 }
35 }
36}
37
38impl<B: Flags> Iterator for Iter<B> {
39 type Item = B;
40
41 fn next(&mut self) -> Option<Self::Item> {
42 match self.inner.next() {
43 Some((_, flag)) => Some(flag),
44 None if !self.done => {
45 self.done = true;
46
47 if !self.inner.remaining().is_empty() {
51 Some(B::from_bits_retain(self.inner.remaining.bits()))
52 } else {
53 None
54 }
55 }
56 None => None,
57 }
58 }
59}
60
61pub struct IterNames<B: 'static> {
68 flags: &'static [Flag<B>],
69 idx: usize,
70 source: B,
71 remaining: B,
72}
73
74impl<B: Flags> IterNames<B> {
75 pub(crate) fn new(flags: &B) -> Self {
76 IterNames {
77 flags: B::FLAGS,
78 idx: 0,
79 remaining: B::from_bits_retain(flags.bits()),
80 source: B::from_bits_retain(flags.bits()),
81 }
82 }
83}
84
85impl<B: 'static> IterNames<B> {
86 #[doc(hidden)]
88 pub const fn __private_const_new(flags: &'static [Flag<B>], source: B, remaining: B) -> Self {
89 IterNames {
90 flags,
91 idx: 0,
92 remaining,
93 source,
94 }
95 }
96
97 pub fn remaining(&self) -> &B {
103 &self.remaining
104 }
105}
106
107impl<B: Flags> Iterator for IterNames<B> {
108 type Item = (&'static str, B);
109
110 fn next(&mut self) -> Option<Self::Item> {
111 while let Some(flag) = self.flags.get(self.idx) {
112 if self.remaining.is_empty() {
114 return None;
115 }
116
117 self.idx += 1;
118
119 if flag.name().is_empty() {
121 continue;
122 }
123
124 let bits = flag.value().bits();
125
126 if self.source.contains(B::from_bits_retain(bits))
135 && self.remaining.intersects(B::from_bits_retain(bits))
136 {
137 self.remaining.remove(B::from_bits_retain(bits));
138
139 return Some((flag.name(), B::from_bits_retain(bits)));
140 }
141 }
142
143 None
144 }
145}
146
147pub struct IterDefinedNames<B: 'static> {
154 flags: &'static [Flag<B>],
155 idx: usize,
156}
157
158impl<B: Flags> IterDefinedNames<B> {
159 pub(crate) fn new() -> Self {
160 IterDefinedNames {
161 flags: B::FLAGS,
162 idx: 0,
163 }
164 }
165}
166
167impl<B: Flags> Iterator for IterDefinedNames<B> {
168 type Item = (&'static str, B);
169
170 fn next(&mut self) -> Option<Self::Item> {
171 while let Some(flag) = self.flags.get(self.idx) {
172 self.idx += 1;
173
174 if flag.is_named() {
176 return Some((flag.name(), B::from_bits_retain(flag.value().bits())));
177 }
178 }
179
180 None
181 }
182}