vt_push_parser/
iter.rs

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