use std::io::BufRead;
use quick_xml::Reader;
use quick_xml::events::Event;
use crate::error::GraphmlError;
use crate::read::builder::Builder;
use crate::read::record::GraphmlRecord;
pub struct GraphmlReader<R: BufRead> {
reader: Reader<R>,
builder: Builder,
buf: Vec<u8>,
done: bool,
}
impl<R: BufRead> GraphmlReader<R> {
pub fn new(input: R) -> Self {
let reader = Reader::from_reader(input);
Self {
reader,
builder: Builder::default(),
buf: Vec::new(),
done: false,
}
}
pub fn next_record(&mut self) -> Result<Option<GraphmlRecord>, GraphmlError> {
while !self.done {
self.buf.clear();
let position = self.reader.buffer_position();
let event = self
.reader
.read_event_into(&mut self.buf)
.map_err(|e| GraphmlError::xml(position, &e))?;
if matches!(event, Event::Eof) {
self.done = true;
self.builder.finish(position)?;
return Ok(None);
}
if let Some(record) = self.builder.handle(&event, position)? {
return Ok(Some(record));
}
}
Ok(None)
}
}
impl<R: BufRead> Iterator for GraphmlReader<R> {
type Item = Result<GraphmlRecord, GraphmlError>;
fn next(&mut self) -> Option<Self::Item> {
self.next_record().transpose()
}
}