//! A parser combinator library with a focus on fully abortable parsing and error handling. use std::fmt::Display; use std::iter::Iterator; pub trait Offsetable { fn get_offset(&self) -> usize; } impl Offsetable for usize { fn get_offset(&self) -> usize { return *self; } } /// A Cloneable Iterator that can report an offset as a count of processed Items. pub trait InputIter: Iterator + Clone + Offsetable {} #[derive(Debug)] pub struct Error { err: E, offset: usize, cause: Option>>, } impl Error { // Constructs a new Error with an offset and no cause. pub fn new(err: E, offset: &S) -> Self { Error { err: err, offset: offset.get_offset(), cause: None, } } // Constructs a new Error with an offset and a cause. pub fn caused_by(err: E, offset: &S, cause: Self) -> Self { Error { err: err, offset: offset.get_offset(), cause: Some(Box::new(cause)), } } pub fn get_err<'a>(&'a self) -> &'a E { &self.err } pub fn get_cause<'a>(&'a self) -> Option<&'a Error> { match self.cause { Some(ref cause) => Some(cause), None => None, } } pub fn get_offset(&self) -> usize { self.offset } } impl Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> { try!(write!(f, "{}", self.err)); match self.cause { Some(ref c) => write!(f, "\n\tCaused By:{}", c), None => Ok(()), } } } /// The result of a parsing attempt. #[derive(Debug)] pub enum Result { /// Complete represents a successful match. Complete(I, O), /// Incomplete indicates input ended before a match could be completed. /// It contains the offset at which the input ended before a match could be completed. Incomplete(usize), /// Fail represents a failed match. Fail(Error), /// Abort represents a match failure that the parser cannot recover from. Abort(Error), } impl Result { /// Returns true if the Result is Complete. pub fn is_complete(&self) -> bool { if let &Result::Complete(_, _) = self { return true; } return false; } /// Returns true if the Result is Incomoplete. pub fn is_incomplete(&self) -> bool { if let &Result::Incomplete(_) = self { return true; } return false; } /// Returns true if the Result is Fail. pub fn is_fail(&self) -> bool { if let &Result::Fail(_) = self { return true; } return false; } /// Returns true if the Result is Abort. pub fn is_abort(&self) -> bool { if let &Result::Abort(_) = self { return true; } return false; } } pub use iter::SliceIter; #[macro_use] pub mod macros; pub mod iter; #[cfg(test)] mod test;