-
Notifications
You must be signed in to change notification settings - Fork 136
Continuation PR for #256: Implement std::error::Error for errors #262
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
Changes from 6 commits
ff679e1
a1f9e6d
51312ea
e985dba
47d1915
9b27f02
e9a2a9b
9b2246c
5b32280
c962d4a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
target | ||
/Cargo.lock | ||
/.cargo/config | ||
.idea |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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,20 @@ pub enum BasicParseErrorKind<'i> { | |
QualifiedRuleInvalid, | ||
} | ||
|
||
impl<'i> BasicParseErrorKind<'i> { | ||
fn description(&self) -> String { | ||
match self { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we move this to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed in the last commit |
||
BasicParseErrorKind::UnexpectedToken(token) => { | ||
format!("Unexpected token: '{}'", token.description()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would just do: |
||
} | ||
BasicParseErrorKind::EndOfInput => "End of input".to_owned(), | ||
BasicParseErrorKind::AtRuleInvalid(message) => format!("Invalid @ rule: {}", message), | ||
BasicParseErrorKind::AtRuleBodyInvalid => "Invalid @ rule body".to_owned(), | ||
BasicParseErrorKind::QualifiedRuleInvalid => "Invalid qualified rule".to_owned(), | ||
} | ||
} | ||
} | ||
|
||
/// The funamental parsing errors that can be triggered by built-in parsing routines. | ||
#[derive(Clone, Debug, PartialEq)] | ||
pub struct BasicParseError<'i> { | ||
|
@@ -62,6 +78,18 @@ pub struct BasicParseError<'i> { | |
pub location: SourceLocation, | ||
} | ||
|
||
impl<'i> fmt::Display for BasicParseError<'i> { | ||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | ||
formatter.write_str(self.kind.description().as_str()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That way this doesn't need the extra allocation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, it may be nice to expose self.location, but that may be fine as a follow-up. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in c962d4a |
||
} | ||
} | ||
|
||
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<BasicParseError<'i>> for ParseError<'i, T> { | ||
#[inline] | ||
fn from(this: BasicParseError<'i>) -> ParseError<'i, T> { | ||
|
@@ -156,6 +184,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) => formatter.write_str(&basic_kind.description()), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can just use |
||
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>, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -191,6 +191,68 @@ impl<'a> Token<'a> { | |
BadUrl(_) | BadString(_) | CloseParenthesis | CloseSquareBracket | CloseCurlyBracket | ||
) | ||
} | ||
|
||
pub(crate) fn description(&self) -> String { | ||
match self { | ||
Ident(name) => format!("A ident token '{}'", name), | ||
AtKeyword(value) => format!("The value '{}' does not include the `@` marker", value), | ||
Hash(value) => format!("The value '{}' does not include the `#` marker", value), | ||
IDHash(value) => format!( | ||
"The value '{}' does not include the `#` marker, but has a valid ID selector", | ||
value | ||
), | ||
QuotedString(value) => format!("The value '{}' does not include the quotes", value), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same for this, I don't know what this is about? |
||
UnquotedUrl(value) => format!( | ||
"The value '{}' does not include the `url(` `)` markers.", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't look right... |
||
value | ||
), | ||
Delim(character) => format!("'{}'", character), | ||
Number { | ||
has_sign, value, .. | ||
} => { | ||
let sign = if has_sign.clone() { '-' } else { '+' }; | ||
format!("{}{}", sign, value.to_string()) | ||
} | ||
Percentage { | ||
has_sign, | ||
unit_value, | ||
.. | ||
} => { | ||
let sign = if has_sign.clone() { '-' } else { '+' }; | ||
format!("{}{}%", sign, unit_value.to_string()) | ||
} | ||
Dimension { | ||
has_sign, | ||
value, | ||
unit, | ||
.. | ||
} => { | ||
let sign = if has_sign.clone() { '-' } else { '+' }; | ||
format!("{}{} {}", sign, value.to_string(), unit) | ||
} | ||
WhiteSpace(whitespace) => format!("whitespace: '{}'", whitespace), | ||
Comment(comment) => format!("The comment: '{}'", comment), | ||
Colon => String::from(":"), | ||
Semicolon => String::from(";"), | ||
Comma => String::from(","), | ||
IncludeMatch => String::from("~="), | ||
DashMatch => String::from("|="), | ||
PrefixMatch => String::from("^="), | ||
SuffixMatch => String::from("$="), | ||
SubstringMatch => String::from("*="), | ||
CDO => String::from("<!--"), | ||
CDC => String::from("-->"), | ||
Function(name) => format!("The value ({}) does not include the `(` marker", name), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be clear, these are legit token types. If the input is |
||
ParenthesisBlock => String::from("("), | ||
SquareBracketBlock => String::from("["), | ||
CurlyBracketBlock => String::from("{"), | ||
BadUrl(url) => format!("Bad url: '{}'", url), | ||
BadString(string) => format!("Bad string: '{}'", string), | ||
CloseParenthesis => "Unclosed parenthesis".to_owned(), | ||
CloseSquareBracket => "Unclosed square bracket".to_owned(), | ||
CloseCurlyBracket => "Unclosed curly bracket".to_owned(), | ||
} | ||
} | ||
} | ||
|
||
#[derive(Clone)] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems a rustfmt bug that should be fixed and undone.