1use std::iter::FusedIterator;
2
3use super::*;
4
5#[doc(hidden)]
6pub struct ArxmlFileIterator {
7 data: AutosarModel,
8 index: usize,
9}
10
11impl ArxmlFileIterator {
12 pub(crate) fn new(data: AutosarModel) -> Self {
13 Self { data, index: 0 }
14 }
15}
16
17impl Iterator for ArxmlFileIterator {
18 type Item = ArxmlFile;
19
20 fn next(&mut self) -> Option<Self::Item> {
21 let model = self.data.0.read();
22 if self.index < model.files.len() {
23 let result = model.files[self.index].clone();
24 self.index += 1;
25 return Some(result);
26 }
27 None
28 }
29}
30
31#[doc(hidden)]
32pub struct ElementsIterator {
33 element: Element,
34 index: usize,
35 last_output: Option<Element>,
36}
37
38impl ElementsIterator {
39 pub(crate) fn new(element: Element) -> Self {
40 Self {
41 element,
42 index: 0,
43 last_output: None,
44 }
45 }
46}
47
48impl Iterator for ElementsIterator {
49 type Item = Element;
50
51 fn next(&mut self) -> Option<Self::Item> {
52 let element = self.element.0.read();
53 while self.index < element.content.len() {
54 let ec = &element.content[self.index];
55 if let ElementContent::Element(sub_element) = ec {
56 if let Some(prev_sub_element) = &self.last_output {
57 if prev_sub_element != sub_element {
58 self.last_output = Some(sub_element.clone());
62 return self.last_output.clone();
63 } else {
64 self.index += 1;
66 }
67 } else {
68 self.last_output = Some(sub_element.clone());
70 return self.last_output.clone();
71 }
72 } else {
73 self.index += 1;
75 }
76 }
77 self.index = usize::MAX; None
79 }
80}
81
82impl FusedIterator for ElementsIterator {}
83
84#[doc(hidden)]
85pub struct ElementContentIterator {
86 element: Element,
87 index: usize,
88}
89
90impl Iterator for ElementContentIterator {
91 type Item = ElementContent;
92
93 fn next(&mut self) -> Option<Self::Item> {
94 let element = self.element.0.read();
95 if self.index < element.content.len() {
96 let ec = &element.content[self.index];
97 self.index += 1;
98 return Some(ec.clone());
99 }
100 None
101 }
102}
103
104impl ElementContentIterator {
105 pub(crate) fn new(element: &Element) -> Self {
106 Self {
107 element: element.clone(),
108 index: 0,
109 }
110 }
111}
112
113#[doc(hidden)]
114pub struct ArxmlFileElementsDfsIterator {
115 weak_file: WeakArxmlFile,
116 dfs_iter: Option<ElementsDfsIterator>,
117}
118
119impl ArxmlFileElementsDfsIterator {
120 pub(crate) fn new(file: &ArxmlFile, max_depth: usize) -> Self {
121 let weak_file = file.downgrade();
122 let dfs_iter = file.model().ok().map(|m| m.elements_dfs_with_max_depth(max_depth));
123 Self { weak_file, dfs_iter }
124 }
125}
126
127impl Iterator for ArxmlFileElementsDfsIterator {
128 type Item = (usize, Element);
129
130 fn next(&mut self) -> Option<Self::Item> {
131 let iter = self.dfs_iter.as_mut()?;
132 let mut next_element = iter.next();
133 while let Some((depth, elem)) = next_element {
134 let files = elem.file_membership_local();
135 if files.is_empty() || files.contains(&self.weak_file) {
136 return Some((depth, elem));
138 }
139 next_element = iter.next_sibling();
141 }
142 None
143 }
144}
145
146#[doc(hidden)]
147pub struct ElementsDfsIterator {
148 elements: Vec<Element>,
149 position: Vec<usize>,
150 max_depth: usize,
151}
152
153impl ElementsDfsIterator {
154 pub(crate) fn new(element: &Element, max_depth: usize) -> Self {
155 Self {
156 elements: vec![element.clone()],
157 position: vec![],
158 max_depth,
159 }
160 }
161
162 pub fn next_sibling(&mut self) -> Option<(usize, Element)> {
163 self.elements.pop();
166 self.position.pop();
167 self.next()
168 }
169}
170
171impl Iterator for ElementsDfsIterator {
172 type Item = (usize, Element);
173
174 fn next(&mut self) -> Option<Self::Item> {
175 while !self.elements.is_empty() {
176 let depth = self.elements.len() - 1;
177 let element = &self.elements[depth];
178
179 if self.position.len() == depth {
180 self.position.push(0);
182
183 return Some((depth, element.clone()));
184 } else {
185 let max = self.max_depth;
187 if (max == 0 || max > depth) && element.content_item_count() > self.position[depth] {
188 if let Some(e) = element.get_sub_element_at(self.position[depth]) {
190 self.elements.push(e);
191 }
192 self.position[depth] += 1;
194 } else {
195 self.elements.pop();
197 self.position.pop();
198 }
199 }
200 }
201
202 None
203 }
204}
205
206impl FusedIterator for ElementsDfsIterator {}
207
208#[doc(hidden)]
209pub struct AttributeIterator {
210 pub(crate) element: Element,
211 pub(crate) index: usize,
212}
213
214impl Iterator for AttributeIterator {
215 type Item = Attribute;
216
217 fn next(&mut self) -> Option<Self::Item> {
218 let element = self.element.0.read();
219 if self.index < element.attributes.len() {
220 let value = element.attributes[self.index].clone();
221 self.index += 1;
222 Some(value)
223 } else {
224 self.index = usize::MAX;
225 None
226 }
227 }
228}
229
230impl FusedIterator for AttributeIterator {}
231
232#[doc(hidden)]
233pub struct IdentifiablesIterator {
234 pub(crate) model: AutosarModel,
235 pub(crate) position: usize,
236}
237
238impl IdentifiablesIterator {
239 pub(crate) fn new(model: &AutosarModel) -> Self {
240 Self {
241 model: model.clone(),
242 position: 0,
243 }
244 }
245}
246
247impl Iterator for IdentifiablesIterator {
248 type Item = (String, WeakElement);
249
250 fn next(&mut self) -> Option<Self::Item> {
251 let model = self.model.0.read();
252 if self.position < model.identifiables.len() {
253 let pos = self.position;
254 self.position += 1;
255 model
256 .identifiables
257 .get_index(pos)
258 .map(|(key, elem)| (key.clone(), elem.clone()))
259 } else {
260 self.position = usize::MAX;
261 None
262 }
263 }
264}
265
266impl FusedIterator for IdentifiablesIterator {}
267
268#[cfg(test)]
269mod test {
270 use super::*;
271
272 #[test]
273 fn elements_iterator() {
274 let model = AutosarModel::new();
275 model.create_file("filename", AutosarVersion::LATEST).unwrap();
276 let element = model
277 .root_element()
278 .create_sub_element(ElementName::ArPackages)
279 .unwrap();
280 element
281 .create_named_sub_element(ElementName::ArPackage, "pkg1")
282 .unwrap();
283 element
284 .create_named_sub_element(ElementName::ArPackage, "pkg2")
285 .unwrap();
286 element
287 .create_named_sub_element(ElementName::ArPackage, "pkg3")
288 .unwrap();
289 element
290 .create_named_sub_element(ElementName::ArPackage, "pkg4")
291 .unwrap();
292
293 assert_eq!(element.sub_elements().count(), 4);
295 let mut iter = element.sub_elements();
296 assert_eq!(iter.next().unwrap().item_name().unwrap(), "pkg1");
297 assert_eq!(iter.next().unwrap().item_name().unwrap(), "pkg2");
298 assert_eq!(iter.next().unwrap().item_name().unwrap(), "pkg3");
299 assert_eq!(iter.next().unwrap().item_name().unwrap(), "pkg4");
300
301 let mut steps = 0;
303 for se in element.sub_elements() {
304 element.remove_sub_element(se).unwrap();
305 steps += 1;
306 }
307 assert_eq!(steps, 4);
308 assert_eq!(element.sub_elements().count(), 0);
309 }
310
311 #[test]
312 fn elements_dfs_iterator() {
313 let sub_sub_element = ElementRaw {
314 parent: ElementOrModel::None,
315 elemname: ElementName::ArPackage, elemtype: ElementType::ROOT, attributes: SmallVec::new(),
318 content: SmallVec::new(),
319 file_membership: HashSet::with_capacity(0),
320 comment: None,
321 }
322 .wrap();
323 let sub_element = ElementRaw {
324 parent: ElementOrModel::None,
325 elemname: ElementName::ArPackages, elemtype: ElementType::ROOT, attributes: SmallVec::new(),
328 content: smallvec::smallvec![
329 ElementContent::Element(sub_sub_element.clone()),
330 ElementContent::Element(sub_sub_element.clone())
331 ],
332 file_membership: HashSet::with_capacity(0),
333 comment: None,
334 }
335 .wrap();
336 let element = ElementRaw {
337 parent: ElementOrModel::None,
338 elemname: ElementName::Autosar, elemtype: ElementType::ROOT, attributes: SmallVec::new(),
341 content: smallvec::smallvec![
342 ElementContent::Element(sub_element.clone()),
343 ElementContent::Element(sub_element.clone())
344 ],
345 file_membership: HashSet::with_capacity(0),
346 comment: None,
347 }
348 .wrap();
349 let dfs_iter = element.elements_dfs();
350 assert_eq!(dfs_iter.count(), 7);
351 }
352
353 #[test]
354 fn elements_dfs_next_sibling() {
355 let model = AutosarModel::new();
356 model.create_file("test", AutosarVersion::LATEST).unwrap();
357 let el_autosar = model.root_element();
358 let el_ar_packages = el_autosar.create_sub_element(ElementName::ArPackages).unwrap();
359 let el_ar_package_1 = el_ar_packages
360 .create_named_sub_element(ElementName::ArPackage, "Package1")
361 .unwrap();
362 el_ar_package_1.create_sub_element(ElementName::Elements).unwrap();
363 let el_ar_package_2 = el_ar_packages
364 .create_named_sub_element(ElementName::ArPackage, "Package2")
365 .unwrap();
366 el_ar_package_2.create_sub_element(ElementName::Elements).unwrap();
367
368 let mut dfs_iter = model.elements_dfs();
369 let (_, item) = dfs_iter.next().unwrap();
370 assert_eq!(item, el_autosar);
371 let (_, item) = dfs_iter.next().unwrap();
372 assert_eq!(item, el_ar_packages);
373 let (_, item) = dfs_iter.next().unwrap();
374 assert_eq!(item, el_ar_package_1);
375 let (_, item) = dfs_iter.next_sibling().unwrap();
377 assert_eq!(item, el_ar_package_2);
378 }
379
380 #[test]
381 fn identifiable_elements_iterator() {
382 let model = AutosarModel::new();
383 model.create_file("test", AutosarVersion::LATEST).unwrap();
384 let el_autosar = model.root_element();
385 let el_ar_packages = el_autosar.create_sub_element(ElementName::ArPackages).unwrap();
386 el_ar_packages
387 .create_named_sub_element(ElementName::ArPackage, "Package1")
388 .unwrap();
389 el_ar_packages
390 .create_named_sub_element(ElementName::ArPackage, "Package2")
391 .unwrap();
392
393 let iter = model.identifiable_elements();
394 assert_eq!(iter.count(), 2);
395 }
396}