use super::{
entities::{Entity,Instance},
state::EntityState,
};
use crate::{
ParserResult,
Source, SourceEvent, ParserEvent, SourceResult, Local,
Parser, Runtime, PipeParser, IntoPipeParser,
};
#[derive(Debug,Clone)]
pub struct Builder {
}
impl Builder {
pub fn new() -> Builder {
Builder { }
}
pub fn create(self) -> EntityParser {
EntityParser(Runtime::new(()))
}
}
pub struct EntityParser(Runtime<EntityState,Entity,()>);
impl Parser for EntityParser {
type Data = Entity;
fn next_event<S: Source>(&mut self, src: &mut S) -> ParserResult<Entity> {
self.0.next_event(src)
}
}
impl IntoPipeParser for EntityParser {
type Piped = PipedEntityParser;
fn into_piped(self) -> Self::Piped {
PipedEntityParser {
parser: self.0,
tmp: None,
}
}
}
pub struct PipedEntityParser {
parser: Runtime<EntityState,Entity,()>,
tmp: Option<Local<SourceEvent>>,
}
impl PipeParser for PipedEntityParser {
fn next_char<S: Source>(&mut self, src: &mut S) -> SourceResult {
Ok(match self.tmp.take() {
Some(local_se) => Some(local_se),
None => match self.parser.next_event(src)? {
Some(local_ent) => {
let (local,ent) = local_ent.into_inner();
match ent {
ParserEvent::Char(c) => Some(local.local(SourceEvent::Char(c))),
ParserEvent::Breaker(b) => Some(local.local(SourceEvent::Breaker(b))),
ParserEvent::Parsed(ent) => match ent.entity {
Instance::Char(c) => Some(local.local(SourceEvent::Char(c))),
Instance::Char2(c1,c2) => {
self.tmp = Some(local.local(SourceEvent::Char(c2)));
Some(local.local(SourceEvent::Char(c1)))
},
},
}
},
None => None,
},
})
}
}
#[cfg(test)]
mod tests {
}