vt_push_parser/
iter.rs

1//! Iterator wrapper around [`VTPushParser`].
2
3use crate::{VTPushParser, event::VTOwnedEvent};
4
5/// A convenience wrapper around [`VTPushParser`] that implements [`Iterator`]
6/// for any `Iterator` of `AsRef<[u8]>`.
7///
8/// _PERFORMANCE NOTE_: This will allocate significantly more than using the
9/// parser directly, but may be more convenient for some use cases.
10pub struct VTIterator<I>
11where
12    I: Iterator,
13    I::Item: AsRef<[u8]>,
14{
15    parser: VTPushParser,
16    iter: I,
17    events: Vec<VTOwnedEvent>,
18}
19
20impl<I> VTIterator<I>
21where
22    I: Iterator,
23    I::Item: AsRef<[u8]>,
24{
25    pub fn new(iter: I) -> Self {
26        Self {
27            parser: VTPushParser::new(),
28            iter,
29            events: Vec::new(),
30        }
31    }
32}
33
34impl<I> Iterator for VTIterator<I>
35where
36    I: Iterator,
37    I::Item: AsRef<[u8]>,
38{
39    type Item = VTOwnedEvent;
40
41    fn next(&mut self) -> Option<Self::Item> {
42        while self.events.is_empty() {
43            if let Some(next) = self.iter.next() {
44                self.parser.feed_with(next.as_ref(), &mut |event| {
45                    self.events.push(event.to_owned());
46                });
47            } else {
48                return None;
49            }
50        }
51
52        self.events.pop()
53    }
54}