use crate::models::*;
use crate::parser::iters::{handle_record_parse_error, record_matches_filters};
use crate::parser::mrt::mrt_elem::PendingElems;
use crate::parser::BgpkitParser;
use crate::{Elementor, Filterable};
use std::io::Read;
#[cfg(test)]
mod tests;
pub struct RecordIterator<R> {
pub parser: BgpkitParser<R>,
pub count: u64,
elementor: Elementor,
}
impl<R> RecordIterator<R> {
pub(crate) fn new(parser: BgpkitParser<R>) -> Self {
RecordIterator {
parser,
count: 0,
elementor: Elementor::new(),
}
}
}
impl<R: Read> Iterator for RecordIterator<R> {
type Item = MrtRecord;
fn next(&mut self) -> Option<MrtRecord> {
if self.parser.text_dump_iter.is_some() {
return None;
}
self.count += 1;
loop {
return match self.parser.next_record() {
Ok(v) => {
if record_matches_filters(&v, &self.parser.filters, &mut self.elementor) {
Some(v)
} else {
continue;
}
}
Err(e) => {
if handle_record_parse_error(&mut self.parser, e.error, e.bytes) {
continue;
}
None
}
};
}
}
}
pub struct ElemIterator<R> {
pending: PendingElems,
record_iter: RecordIterator<R>,
elementor: Elementor,
count: u64,
}
impl<R> ElemIterator<R> {
pub(crate) fn new(parser: BgpkitParser<R>) -> Self {
ElemIterator {
record_iter: RecordIterator::new(parser),
count: 0,
pending: PendingElems::Empty,
elementor: Elementor::new(),
}
}
}
impl<R: Read> Iterator for ElemIterator<R> {
type Item = BgpElem;
fn next(&mut self) -> Option<BgpElem> {
self.count += 1;
if let Some(iter) = &mut self.record_iter.parser.text_dump_iter {
for elem in iter.by_ref() {
if elem.match_filters(&self.record_iter.parser.filters) {
return Some(elem);
}
}
return None;
}
loop {
while let Some(elem) = self.pending.next_elem(self.elementor.peer_table.as_ref()) {
if elem.match_filters(&self.record_iter.parser.filters) {
return Some(elem);
}
}
let record = self.record_iter.next()?;
self.pending = self.elementor.ingest(record);
}
}
}