arch_pkg_db/text/multi/
iter.rs1use super::MultiTextCollection;
2use crate::{
3 Text, TextCollection,
4 text::iter::{TextIntoIter, TextIter, TextIterMut},
5 value::RepositoryName,
6};
7use core::{iter::FusedIterator, slice};
8use std::vec;
9
10#[derive(Debug, Clone)]
13pub struct MultiTextIter<'a> {
14 current: Option<(RepositoryName<'a>, TextIter<'a>)>,
15 remaining: slice::Iter<'a, (RepositoryName<'a>, TextCollection)>,
16}
17
18impl<'a> MultiTextIter<'a> {
19 fn blank(collections: &'a Vec<(RepositoryName<'a>, TextCollection)>) -> Self {
23 MultiTextIter {
24 current: None,
25 remaining: collections.iter(),
26 }
27 }
28
29 fn next_stage(&mut self) {
31 debug_assert!(
32 self.current.is_none(),
33 "next_stage must only be called after current has been exhausted",
34 );
35 self.current = self
36 .remaining
37 .next()
38 .map(|(repository, collection)| (*repository, collection.iter()));
39 }
40}
41
42impl<'a> Iterator for MultiTextIter<'a> {
43 type Item = (RepositoryName<'a>, &'a Text);
44
45 fn next(&mut self) -> Option<Self::Item> {
46 loop {
47 let (repository, text_iter) = self.current.as_mut()?;
48
49 if let Some(text) = text_iter.next() {
50 return Some((*repository, text));
51 }
52
53 self.current = None;
54 self.next_stage();
55 }
56 }
57}
58
59impl FusedIterator for MultiTextIter<'_> {}
60
61impl<'a> MultiTextCollection<'a> {
62 pub fn iter(&'a self) -> MultiTextIter<'a> {
65 let mut iter = MultiTextIter::blank(&self.internal);
66 iter.next_stage();
67 iter
68 }
69}
70
71#[derive(Debug)]
74pub struct MultiTextIterMut<'a> {
75 current: Option<(RepositoryName<'a>, TextIterMut<'a>)>,
76 remaining: slice::IterMut<'a, (RepositoryName<'a>, TextCollection)>,
77}
78
79impl<'a> MultiTextIterMut<'a> {
80 fn blank(collections: &'a mut Vec<(RepositoryName<'a>, TextCollection)>) -> Self {
84 MultiTextIterMut {
85 current: None,
86 remaining: collections.iter_mut(),
87 }
88 }
89
90 fn next_stage(&mut self) {
92 debug_assert!(
93 self.current.is_none(),
94 "next_stage must only be called after current has been exhausted",
95 );
96 self.current = self
97 .remaining
98 .next()
99 .map(|(repository, collection)| (*repository, collection.iter_mut()));
100 }
101}
102
103impl<'a> Iterator for MultiTextIterMut<'a> {
104 type Item = (RepositoryName<'a>, &'a mut Text);
105
106 fn next(&mut self) -> Option<Self::Item> {
107 loop {
108 let (repository, text_iter) = self.current.as_mut()?;
109
110 if let Some(text) = text_iter.next() {
111 return Some((*repository, text));
112 }
113
114 self.current = None;
115 self.next_stage();
116 }
117 }
118}
119
120impl FusedIterator for MultiTextIterMut<'_> {}
121
122impl<'a> MultiTextCollection<'a> {
123 pub fn iter_mut(&'a mut self) -> MultiTextIterMut<'a> {
126 let mut iter = MultiTextIterMut::blank(&mut self.internal);
127 iter.next_stage();
128 iter
129 }
130}
131
132#[derive(Debug, Clone)]
135pub struct MultiTextIntoIter<'a> {
136 current: Option<(RepositoryName<'a>, TextIntoIter)>,
137 remaining: vec::IntoIter<(RepositoryName<'a>, TextCollection)>,
138}
139
140impl<'a> MultiTextIntoIter<'a> {
141 fn blank(collections: Vec<(RepositoryName<'a>, TextCollection)>) -> Self {
145 MultiTextIntoIter {
146 current: None,
147 remaining: collections.into_iter(),
148 }
149 }
150
151 fn next_stage(&mut self) {
153 debug_assert!(
154 self.current.is_none(),
155 "next_stage must only be called after current has been exhausted",
156 );
157 self.current = self
158 .remaining
159 .next()
160 .map(|(repository, collection)| (repository, collection.into_iter()));
161 }
162}
163
164impl<'a> Iterator for MultiTextIntoIter<'a> {
165 type Item = (RepositoryName<'a>, Text);
166
167 fn next(&mut self) -> Option<Self::Item> {
168 loop {
169 let (repository, text_iter) = self.current.as_mut()?;
170
171 if let Some(text) = text_iter.next() {
172 return Some((*repository, text));
173 }
174
175 self.current = None;
176 self.next_stage();
177 }
178 }
179}
180
181impl FusedIterator for MultiTextIntoIter<'_> {}
182
183impl<'a> IntoIterator for MultiTextCollection<'a> {
184 type Item = (RepositoryName<'a>, Text);
185 type IntoIter = MultiTextIntoIter<'a>;
186
187 fn into_iter(self) -> Self::IntoIter {
188 let mut iter = MultiTextIntoIter::blank(self.internal);
189 iter.next_stage();
190 iter
191 }
192}