use self::error::Result;
use std::io::Read;
pub use self::error::{Error, ErrorKind};
use crate::common::{FbxFormatType, OwnedProperty};
mod error;
mod parser;
#[derive(Debug, Clone)]
pub enum FbxEvent {
StartFbx(FbxFormatType),
EndFbx,
StartNode {
name: String,
properties: Vec<OwnedProperty>,
},
EndNode,
Comment(String),
}
impl FbxEvent {
pub fn as_writer_event(&self) -> crate::writer::FbxEvent<'_> {
use crate::writer::FbxEvent as WriterEvent;
match *self {
FbxEvent::StartFbx(ref format) => WriterEvent::StartFbx(*format),
FbxEvent::EndFbx => WriterEvent::EndFbx,
FbxEvent::StartNode {
ref name,
ref properties,
} => WriterEvent::StartNode {
name: &name,
properties: properties.iter().map(|p| p.borrow()).collect(),
},
FbxEvent::EndNode => WriterEvent::EndNode,
FbxEvent::Comment(ref msg) => WriterEvent::Comment(&msg),
}
}
}
pub struct EventReader<R: Read> {
source: R,
parser: parser::Parser,
}
impl<R: Read> EventReader<R> {
pub fn new(source: R) -> Self {
EventReader {
source,
parser: parser::Parser::new(ParserConfig::new()),
}
}
pub fn new_with_config(source: R, config: ParserConfig) -> Self {
EventReader {
source,
parser: parser::Parser::new(config),
}
}
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Result<FbxEvent> {
self.parser.next(&mut self.source)
}
}
impl<R: Read> IntoIterator for EventReader<R> {
type Item = Result<FbxEvent>;
type IntoIter = Events<R>;
fn into_iter(self) -> Events<R> {
Events {
reader: self,
finished: false,
}
}
}
pub struct Events<R: Read> {
reader: EventReader<R>,
finished: bool,
}
impl<R: Read> Events<R> {
#[allow(dead_code)]
fn into_inner(self) -> EventReader<R> {
self.reader
}
}
impl<R: Read> Iterator for Events<R> {
type Item = Result<FbxEvent>;
fn next(&mut self) -> Option<Result<FbxEvent>> {
if self.finished {
None
} else {
let ev = self.reader.next();
match ev {
Ok(FbxEvent::EndFbx) | Err(_) => self.finished = true,
_ => {}
}
Some(ev)
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ParserConfig {
pub ignore_comments: bool,
}
impl ParserConfig {
pub fn new() -> Self {
ParserConfig {
ignore_comments: false,
}
}
pub fn create_reader<R: Read>(self, source: R) -> EventReader<R> {
EventReader::new_with_config(source, self)
}
pub fn ignore_comments(mut self, value: bool) -> Self {
self.ignore_comments = value;
self
}
}
impl Default for ParserConfig {
fn default() -> ParserConfig {
ParserConfig::new()
}
}