use super::constants::*;
use crate::block;
use crate::error::ExpectedEntries;
use crate::parser::error;
use crate::reader;
enum Context {
Initial,
Comment,
FinishDataEnd,
FinishSeparator,
Error,
}
pub enum Result {
DataEnd,
Separator,
}
pub struct DataEndOrSeparator {
context: Context,
error_source: error::Source,
}
impl DataEndOrSeparator {
pub fn new() -> DataEndOrSeparator {
DataEndOrSeparator {
context: Context::Initial,
error_source: error::Source::NoContent,
}
}
}
impl Default for DataEndOrSeparator {
fn default() -> Self {
return DataEndOrSeparator::new();
}
}
impl block::Trait for DataEndOrSeparator {
type Result = Result;
fn advance_result(&mut self, read_byte: u8) -> block::AdvanceResult {
match (&self.context, read_byte) {
(&Context::Initial,
DENOMINATOR_COMMENT) => {
self.context = Context::Comment;
return block::AdvanceResult::Continuous;
},
(&Context::Initial,
DENOMINATOR_NEW_LINE)
| (&Context::Initial,
DENOMINATOR_SPACE)
| (&Context::Initial,
DENOMINATOR_TAB) => {
return block::AdvanceResult::Continuous;
},
(&Context::Initial,
DENOMINATOR_DATA_END) => {
self.context = Context::FinishDataEnd;
return block::AdvanceResult::Finished;
},
(&Context::Initial,
DENOMINATOR_SEPARATOR) => {
self.context = Context::FinishSeparator;
return block::AdvanceResult::Finished;
},
(&Context::Initial,
_) => {
self.error_source = error::Source::UnexpectedToken(
error::UnexpectedToken{
token_expected_entries: ExpectedEntries::from(vec![DENOMINATOR_DATA_START as char]),
token_found: read_byte as char,
}
);
self.context = Context::Error;
return block::AdvanceResult::Error;
},
(&Context::Comment,
DENOMINATOR_NEW_LINE) => {
self.context = Context::Initial;
return block::AdvanceResult::Continuous;
},
(&Context::Comment,
_) => {
return block::AdvanceResult::Continuous;
},
(&Context::FinishSeparator, _)
| (&Context::FinishDataEnd, _) => {
return block::AdvanceResult::Finished;
},
(&Context::Error,
_) => {
return block::AdvanceResult::Error;
},
}
}
fn into_result(self) -> std::result::Result<Result, error::Source> {
match self.context {
Context::Initial
| Context::Comment
| Context::Error => {
return Err(self.error_source);
},
Context::FinishSeparator => {
return Ok(Result::Separator);
},
Context::FinishDataEnd => {
return Ok(Result::DataEnd);
},
}
}
}