1use super::{Attribute, Block, Body, Structure};
4use std::iter::FusedIterator;
5use std::slice;
6use std::vec;
7
8macro_rules! impl_find_map_iterator {
9 ($ty:ident$(<$lt:lifetime>)?, $item:ty, $map:expr) => {
10 impl$(<$lt>)* Iterator for $ty$(<$lt>)* {
11 type Item = $item;
12
13 fn next(&mut self) -> Option<Self::Item> {
14 self.iter.find_map($map)
15 }
16 }
17
18 impl$(<$lt>)* DoubleEndedIterator for $ty$(<$lt>)* {
19 fn next_back(&mut self) -> Option<Self::Item> {
20 loop {
21 match self.iter.next_back() {
22 Some(val) => {
23 if let Some(val) = $map(val) {
24 return Some(val);
25 }
26 }
27 None => return None,
28 };
29 }
30 }
31 }
32
33 impl$(<$lt>)* FusedIterator for $ty$(<$lt>)* {}
34 };
35}
36
37macro_rules! impl_exact_size_iterator {
38 ($ty:ident$(<$lt:lifetime>)?, $item:ty) => {
39 impl$(<$lt>)* Iterator for $ty$(<$lt>)* {
40 type Item = $item;
41
42 fn next(&mut self) -> Option<Self::Item> {
43 self.iter.next()
44 }
45
46 fn size_hint(&self) -> (usize, Option<usize>) {
47 self.iter.size_hint()
48 }
49 }
50
51 impl$(<$lt>)* DoubleEndedIterator for $ty$(<$lt>)* {
52 fn next_back(&mut self) -> Option<Self::Item> {
53 self.iter.next_back()
54 }
55 }
56
57 impl$(<$lt>)* ExactSizeIterator for $ty$(<$lt>)* {
58 fn len(&self) -> usize {
59 self.iter.len()
60 }
61 }
62
63 impl$(<$lt>)* FusedIterator for $ty$(<$lt>)* {}
64 };
65}
66
67impl<T> Extend<T> for Body
68where
69 T: Into<Structure>,
70{
71 fn extend<I>(&mut self, iterable: I)
72 where
73 I: IntoIterator<Item = T>,
74 {
75 self.0.extend(iterable.into_iter().map(Into::into));
76 }
77}
78
79impl<T> FromIterator<T> for Body
80where
81 T: Into<Structure>,
82{
83 fn from_iter<I>(iter: I) -> Self
84 where
85 I: IntoIterator<Item = T>,
86 {
87 let iter = iter.into_iter();
88 let lower = iter.size_hint().0;
89 let mut body = Body(Vec::with_capacity(lower));
90 body.extend(iter);
91 body
92 }
93}
94
95impl IntoIterator for Body {
96 type Item = Structure;
97
98 type IntoIter = IntoIter;
99
100 fn into_iter(self) -> Self::IntoIter {
101 IntoIter::new(self)
102 }
103}
104
105impl<'a> IntoIterator for &'a Body {
106 type Item = &'a Structure;
107
108 type IntoIter = Iter<'a>;
109
110 fn into_iter(self) -> Self::IntoIter {
111 self.iter()
112 }
113}
114
115impl<'a> IntoIterator for &'a mut Body {
116 type Item = &'a mut Structure;
117
118 type IntoIter = IterMut<'a>;
119
120 fn into_iter(self) -> Self::IntoIter {
121 self.iter_mut()
122 }
123}
124
125#[derive(Debug, Clone)]
130pub struct Iter<'a> {
131 iter: slice::Iter<'a, Structure>,
132}
133
134impl<'a> Iter<'a> {
135 pub(super) fn new(body: &'a Body) -> Iter<'a> {
136 Iter {
137 iter: body.0.iter(),
138 }
139 }
140}
141
142impl_exact_size_iterator!(Iter<'a>, &'a Structure);
143
144#[derive(Debug)]
149pub struct IterMut<'a> {
150 iter: slice::IterMut<'a, Structure>,
151}
152
153impl<'a> IterMut<'a> {
154 pub(super) fn new(body: &'a mut Body) -> IterMut<'a> {
155 IterMut {
156 iter: body.0.iter_mut(),
157 }
158 }
159}
160
161impl_exact_size_iterator!(IterMut<'a>, &'a mut Structure);
162
163#[derive(Debug, Clone)]
171pub struct IntoIter {
172 iter: vec::IntoIter<Structure>,
173}
174
175impl IntoIter {
176 pub(super) fn new(body: Body) -> IntoIter {
177 IntoIter {
178 iter: body.0.into_iter(),
179 }
180 }
181}
182
183impl_exact_size_iterator!(IntoIter, Structure);
184
185#[derive(Debug, Clone)]
190pub struct Attributes<'a> {
191 iter: Iter<'a>,
192}
193
194impl<'a> Attributes<'a> {
195 pub(super) fn new(body: &'a Body) -> Attributes<'a> {
196 Attributes { iter: body.iter() }
197 }
198}
199
200impl_find_map_iterator!(Attributes<'a>, &'a Attribute, Structure::as_attribute);
201
202#[derive(Debug)]
207pub struct AttributesMut<'a> {
208 iter: IterMut<'a>,
209}
210
211impl<'a> AttributesMut<'a> {
212 pub(super) fn new(body: &'a mut Body) -> AttributesMut<'a> {
213 AttributesMut {
214 iter: body.iter_mut(),
215 }
216 }
217}
218
219impl_find_map_iterator!(
220 AttributesMut<'a>,
221 &'a mut Attribute,
222 Structure::as_attribute_mut
223);
224
225#[derive(Debug, Clone)]
230pub struct IntoAttributes {
231 iter: IntoIter,
232}
233
234impl IntoAttributes {
235 pub(super) fn new(body: Body) -> IntoAttributes {
236 IntoAttributes {
237 iter: body.into_iter(),
238 }
239 }
240}
241
242impl_find_map_iterator!(IntoAttributes, Attribute, Structure::into_attribute);
243
244#[derive(Debug, Clone)]
249pub struct Blocks<'a> {
250 iter: Iter<'a>,
251}
252
253impl<'a> Blocks<'a> {
254 pub(super) fn new(body: &'a Body) -> Blocks<'a> {
255 Blocks { iter: body.iter() }
256 }
257}
258
259impl_find_map_iterator!(Blocks<'a>, &'a Block, Structure::as_block);
260
261#[derive(Debug)]
266pub struct BlocksMut<'a> {
267 iter: IterMut<'a>,
268}
269
270impl<'a> BlocksMut<'a> {
271 pub(super) fn new(body: &'a mut Body) -> BlocksMut<'a> {
272 BlocksMut {
273 iter: body.iter_mut(),
274 }
275 }
276}
277
278impl_find_map_iterator!(BlocksMut<'a>, &'a mut Block, Structure::as_block_mut);
279
280#[derive(Debug, Clone)]
285pub struct IntoBlocks {
286 iter: IntoIter,
287}
288
289impl IntoBlocks {
290 pub(super) fn new(body: Body) -> IntoBlocks {
291 IntoBlocks {
292 iter: body.into_iter(),
293 }
294 }
295}
296
297impl_find_map_iterator!(IntoBlocks, Block, Structure::into_block);