diff --git a/.gitignore b/.gitignore index 0b837eae..39d7405d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ target /Cargo.lock /.cargo/config +.idea diff --git a/src/parser.rs b/src/parser.rs index f04628db..9624056e 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -5,6 +5,8 @@ use crate::cow_rc_str::CowRcStr; use crate::tokenizer::{SourceLocation, SourcePosition, Token, Tokenizer}; use smallvec::SmallVec; +use std::error::Error; +use std::fmt; use std::ops::BitOr; use std::ops::Range; @@ -53,6 +55,19 @@ pub enum BasicParseErrorKind<'i> { QualifiedRuleInvalid, } +impl<'i> fmt::Display for BasicParseErrorKind<'i> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self { + BasicParseErrorKind::UnexpectedToken(token) => { + write!(formatter, "Unexpected token: {:?}", token) + } + BasicParseErrorKind::EndOfInput => formatter.write_str("End of input"), + BasicParseErrorKind::AtRuleInvalid(message) => write!(formatter, "Invalid @ rule: {}", message), + BasicParseErrorKind::AtRuleBodyInvalid => formatter.write_str("Invalid @ rule body"), + BasicParseErrorKind::QualifiedRuleInvalid => formatter.write_str("Invalid qualified rule"), + } + } +} /// The fundamental parsing errors that can be triggered by built-in parsing routines. #[derive(Clone, Debug, PartialEq)] pub struct BasicParseError<'i> { @@ -62,6 +77,18 @@ pub struct BasicParseError<'i> { pub location: SourceLocation, } +impl<'i> fmt::Display for BasicParseError<'i> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + self.kind.fmt(formatter) + } +} + +impl<'i> Error for BasicParseError<'i> { + fn description(&self) -> &str { + "A BasicParseError has occurred, please use the Display trait to determine it's kind" + } +} + impl<'i, T> From> for ParseError<'i, T> { #[inline] fn from(this: BasicParseError<'i>) -> ParseError<'i, T> { @@ -156,6 +183,27 @@ impl<'i, T> ParseError<'i, T> { } } +impl<'i, T> fmt::Display for ParseError<'i, T> +where + T: fmt::Display, +{ + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match &self.kind { + ParseErrorKind::Basic(basic_kind) => basic_kind.fmt(formatter), + ParseErrorKind::Custom(custom_type) => custom_type.fmt(formatter), + } + } +} + +impl<'i, T> Error for ParseError<'i, T> +where + T: Error, +{ + fn description(&self) -> &str { + "A ParseError has occurred, please use the Display trait to determine it's kind" + } +} + /// The owned input for a parser. pub struct ParserInput<'i> { tokenizer: Tokenizer<'i>,