Skip to content

Make ParseError a std::error::Error #332

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 27, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use crate::cow_rc_str::CowRcStr;
use crate::tokenizer::{SourceLocation, SourcePosition, Token, Tokenizer};
use smallvec::SmallVec;
use std::fmt;
use std::ops::BitOr;
use std::ops::Range;

Expand Down Expand Up @@ -53,6 +54,24 @@ pub enum BasicParseErrorKind<'i> {
QualifiedRuleInvalid,
}

impl<'i> fmt::Display for BasicParseErrorKind<'i> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
BasicParseErrorKind::UnexpectedToken(token) => {
write!(f, "unexpected token: {:?}", token)
}
BasicParseErrorKind::EndOfInput => write!(f, "unexpected end of input"),
BasicParseErrorKind::AtRuleInvalid(rule) => {
write!(f, "invalid @ rule encountered: '@{}'", rule)
}
BasicParseErrorKind::AtRuleBodyInvalid => write!(f, "invalid @ rule body encountered"),
BasicParseErrorKind::QualifiedRuleInvalid => {
write!(f, "invalid qualified rule encountered")
}
}
}
}

/// The fundamental parsing errors that can be triggered by built-in parsing routines.
#[derive(Clone, Debug, PartialEq)]
pub struct BasicParseError<'i> {
Expand Down Expand Up @@ -123,6 +142,15 @@ impl<'i, T> ParseErrorKind<'i, T> {
}
}

impl<'i, E: fmt::Display> fmt::Display for ParseErrorKind<'i, E> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ParseErrorKind::Basic(ref basic) => basic.fmt(f),
ParseErrorKind::Custom(ref custom) => custom.fmt(f),
}
}
}

/// Extensible parse errors that can be encountered by client parsing implementations.
#[derive(Clone, Debug, PartialEq)]
pub struct ParseError<'i, E> {
Expand All @@ -137,7 +165,7 @@ impl<'i, T> ParseError<'i, T> {
pub fn basic(self) -> BasicParseError<'i> {
match self.kind {
ParseErrorKind::Basic(kind) => BasicParseError {
kind: kind,
kind,
location: self.location,
},
ParseErrorKind::Custom(_) => panic!("Not a basic parse error"),
Expand All @@ -156,6 +184,14 @@ impl<'i, T> ParseError<'i, T> {
}
}

impl<'i, E: fmt::Display> fmt::Display for ParseError<'i, E> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.kind.fmt(f)
}
}

impl<'i, E: fmt::Display + fmt::Debug> std::error::Error for ParseError<'i, E> {}

/// The owned input for a parser.
pub struct ParserInput<'i> {
tokenizer: Tokenizer<'i>,
Expand Down Expand Up @@ -396,7 +432,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
#[inline]
pub fn new_basic_error(&self, kind: BasicParseErrorKind<'i>) -> BasicParseError<'i> {
BasicParseError {
kind: kind,
kind,
location: self.current_source_location(),
}
}
Expand Down