bgpkit_parser/parser/iters/
fallible.rs1use crate::error::{ParserError, ParserErrorWithBytes};
9use crate::models::*;
10use crate::parser::BgpkitParser;
11use crate::{Elementor, Filterable};
12use std::io::Read;
13
14pub struct FallibleRecordIterator<R> {
19 parser: BgpkitParser<R>,
20 elementor: Elementor,
21}
22
23impl<R> FallibleRecordIterator<R> {
24 pub(crate) fn new(parser: BgpkitParser<R>) -> Self {
25 FallibleRecordIterator {
26 parser,
27 elementor: Elementor::new(),
28 }
29 }
30}
31
32impl<R: Read> Iterator for FallibleRecordIterator<R> {
33 type Item = Result<MrtRecord, ParserErrorWithBytes>;
34
35 fn next(&mut self) -> Option<Self::Item> {
36 loop {
37 match self.parser.next_record() {
38 Ok(record) => {
39 let filters = &self.parser.filters;
41 if filters.is_empty() {
42 return Some(Ok(record));
43 }
44
45 if let MrtMessage::TableDumpV2Message(TableDumpV2Message::PeerIndexTable(_)) =
47 &record.message
48 {
49 let _ = self.elementor.record_to_elems(record.clone());
50 return Some(Ok(record));
51 }
52
53 let elems = self.elementor.record_to_elems(record.clone());
55 if elems.iter().any(|e| e.match_filters(filters)) {
56 return Some(Ok(record));
57 }
58 continue;
60 }
61 Err(e) if matches!(e.error, ParserError::EofExpected) => {
62 return None;
64 }
65 Err(e) => {
66 return Some(Err(e));
68 }
69 }
70 }
71 }
72}
73
74pub struct FallibleElemIterator<R> {
79 cache_elems: Vec<BgpElem>,
80 record_iter: FallibleRecordIterator<R>,
81 elementor: Elementor,
82}
83
84impl<R> FallibleElemIterator<R> {
85 pub(crate) fn new(parser: BgpkitParser<R>) -> Self {
86 FallibleElemIterator {
87 record_iter: FallibleRecordIterator::new(parser),
88 cache_elems: vec![],
89 elementor: Elementor::new(),
90 }
91 }
92}
93
94impl<R: Read> Iterator for FallibleElemIterator<R> {
95 type Item = Result<BgpElem, ParserErrorWithBytes>;
96
97 fn next(&mut self) -> Option<Self::Item> {
98 loop {
99 if !self.cache_elems.is_empty() {
101 if let Some(elem) = self.cache_elems.pop() {
102 if elem.match_filters(&self.record_iter.parser.filters) {
103 return Some(Ok(elem));
104 }
105 continue;
107 }
108 }
109
110 match self.record_iter.next() {
112 None => return None,
113 Some(Err(e)) => return Some(Err(e)),
114 Some(Ok(record)) => {
115 let mut elems = self.elementor.record_to_elems(record);
116 if elems.is_empty() {
117 continue;
119 }
120 elems.reverse();
122 self.cache_elems = elems;
123 continue;
124 }
125 }
126 }
127 }
128}
129
130#[cfg(test)]
131mod tests {
132 use super::*;
133 use std::io::Cursor;
134
135 fn create_test_parser_with_errors() -> BgpkitParser<Cursor<Vec<u8>>> {
137 let invalid_data = vec![
139 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, ];
146
147 let cursor = Cursor::new(invalid_data);
148 BgpkitParser::from_reader(cursor)
149 }
150
151 fn create_test_parser_with_valid_data() -> BgpkitParser<Cursor<Vec<u8>>> {
153 let cursor = Cursor::new(vec![]);
156 BgpkitParser::from_reader(cursor)
157 }
158
159 #[test]
160 fn test_fallible_record_iterator_with_errors() {
161 let parser = create_test_parser_with_errors();
162 let mut iter = parser.into_fallible_record_iter();
163
164 let result = iter.next();
166 assert!(result.is_some());
167 assert!(result.unwrap().is_err());
168 }
169
170 #[test]
171 fn test_fallible_record_iterator_eof() {
172 let parser = create_test_parser_with_valid_data();
173 let mut iter = parser.into_fallible_record_iter();
174
175 let result = iter.next();
177 assert!(result.is_none());
178 }
179
180 #[test]
181 fn test_fallible_elem_iterator_with_errors() {
182 let parser = create_test_parser_with_errors();
183 let mut iter = parser.into_fallible_elem_iter();
184
185 let result = iter.next();
187 assert!(result.is_some());
188 assert!(result.unwrap().is_err());
189 }
190
191 #[test]
192 fn test_fallible_elem_iterator_eof() {
193 let parser = create_test_parser_with_valid_data();
194 let mut iter = parser.into_fallible_elem_iter();
195
196 let result = iter.next();
198 assert!(result.is_none());
199 }
200}