bgpkit_parser/parser/iters/
fallible.rs1use super::next_fallible_record;
9use crate::error::ParserErrorWithBytes;
10use crate::models::*;
11use crate::parser::BgpkitParser;
12use crate::{Elementor, Filterable};
13use std::io::Read;
14
15pub struct FallibleRecordIterator<R> {
20 parser: BgpkitParser<R>,
21 elementor: Elementor,
22 finished: bool,
23}
24
25impl<R> FallibleRecordIterator<R> {
26 pub(crate) fn new(parser: BgpkitParser<R>) -> Self {
27 FallibleRecordIterator {
28 parser,
29 elementor: Elementor::new(),
30 finished: false,
31 }
32 }
33}
34
35impl<R: Read> Iterator for FallibleRecordIterator<R> {
36 type Item = Result<MrtRecord, ParserErrorWithBytes>;
37
38 fn next(&mut self) -> Option<Self::Item> {
39 if self.parser.text_dump_iter.is_some() {
42 return None;
43 }
44 loop {
45 match next_fallible_record(&mut self.parser, &mut self.finished) {
46 Some(Ok(record)) => {
47 let filters = &self.parser.filters;
49 if filters.is_empty() {
50 return Some(Ok(record));
51 }
52
53 if let MrtMessage::TableDumpV2Message(TableDumpV2Message::PeerIndexTable(_)) =
55 &record.message
56 {
57 let _ = self.elementor.record_to_elems(record.clone());
58 return Some(Ok(record));
59 }
60
61 let elems = self.elementor.record_to_elems(record.clone());
63 if elems.iter().any(|e| e.match_filters(filters)) {
64 return Some(Ok(record));
65 }
66 continue;
68 }
69 None => return None,
70 Some(Err(e)) => {
71 return Some(Err(e));
73 }
74 }
75 }
76 }
77}
78
79pub struct FallibleElemIterator<R> {
84 cache_elems: Vec<BgpElem>,
85 record_iter: FallibleRecordIterator<R>,
86 elementor: Elementor,
87}
88
89impl<R> FallibleElemIterator<R> {
90 pub(crate) fn new(parser: BgpkitParser<R>) -> Self {
91 FallibleElemIterator {
92 record_iter: FallibleRecordIterator::new(parser),
93 cache_elems: vec![],
94 elementor: Elementor::new(),
95 }
96 }
97}
98
99impl<R: Read> Iterator for FallibleElemIterator<R> {
100 type Item = Result<BgpElem, ParserErrorWithBytes>;
101
102 fn next(&mut self) -> Option<Self::Item> {
103 loop {
104 if let Some(iter) = &mut self.record_iter.parser.text_dump_iter {
106 for elem in iter.by_ref() {
107 if elem.match_filters(&self.record_iter.parser.filters) {
108 return Some(Ok(elem));
109 }
110 }
111 return None;
112 }
113
114 if !self.cache_elems.is_empty() {
116 if let Some(elem) = self.cache_elems.pop() {
117 if elem.match_filters(&self.record_iter.parser.filters) {
118 return Some(Ok(elem));
119 }
120 continue;
122 }
123 }
124
125 match self.record_iter.next() {
127 None => return None,
128 Some(Err(e)) => return Some(Err(e)),
129 Some(Ok(record)) => {
130 let mut elems = self.elementor.record_to_elems(record);
131 if elems.is_empty() {
132 continue;
134 }
135 elems.reverse();
137 self.cache_elems = elems;
138 continue;
139 }
140 }
141 }
142 }
143}
144
145#[cfg(test)]
146mod tests {
147 use super::*;
148 use std::io::Cursor;
149
150 fn create_test_parser_with_errors() -> BgpkitParser<Cursor<Vec<u8>>> {
152 let invalid_data = vec![
154 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, ];
161
162 let cursor = Cursor::new(invalid_data);
163 BgpkitParser::from_reader(cursor)
164 }
165
166 fn create_test_parser_with_valid_data() -> BgpkitParser<Cursor<Vec<u8>>> {
168 let cursor = Cursor::new(vec![]);
171 BgpkitParser::from_reader(cursor)
172 }
173
174 #[test]
175 fn test_fallible_record_iterator_with_errors() {
176 let parser = create_test_parser_with_errors();
177 let mut iter = parser.into_fallible_record_iter();
178
179 let result = iter.next();
181 assert!(result.is_some());
182 assert!(result.unwrap().is_err());
183 }
184
185 #[test]
186 fn test_fallible_record_iterator_eof() {
187 let parser = create_test_parser_with_valid_data();
188 let mut iter = parser.into_fallible_record_iter();
189
190 let result = iter.next();
192 assert!(result.is_none());
193 }
194
195 #[test]
196 fn test_fallible_elem_iterator_with_errors() {
197 let parser = create_test_parser_with_errors();
198 let mut iter = parser.into_fallible_elem_iter();
199
200 let result = iter.next();
202 assert!(result.is_some());
203 assert!(result.unwrap().is_err());
204 }
205
206 #[test]
207 fn test_fallible_elem_iterator_eof() {
208 let parser = create_test_parser_with_valid_data();
209 let mut iter = parser.into_fallible_elem_iter();
210
211 let result = iter.next();
213 assert!(result.is_none());
214 }
215}