Skip to content

Commit bcbdb8a

Browse files
committed
Merge branch 'error-tokens'
2 parents dc8d657 + 8bf3326 commit bcbdb8a

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

src/parser.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,27 @@ impl<'i, 't> Parser<'i, 't> {
625625
_ => Err(())
626626
}
627627
}
628+
629+
/// Parse the input until exhaustion and check that it contains no “error” token.
630+
///
631+
/// See `Token::is_parse_error`. This also checks nested blocks and functions recursively.
632+
#[inline]
633+
pub fn expect_no_error_token(&mut self) -> Result<(), ()> {
634+
loop {
635+
match self.next_including_whitespace_and_comments() {
636+
Ok(Token::Function(_)) | Ok(Token::ParenthesisBlock) |
637+
Ok(Token::SquareBracketBlock) | Ok(Token::CurlyBracketBlock) => {
638+
try!(self.parse_nested_block(|input| input.expect_no_error_token()))
639+
}
640+
Ok(token) => {
641+
if token.is_parse_error() {
642+
return Err(())
643+
}
644+
}
645+
Err(()) => return Ok(())
646+
}
647+
}
648+
}
628649
}
629650

630651

src/tests.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,19 @@ fn stylesheet_from_bytes() {
266266
}
267267

268268

269+
#[test]
270+
fn expect_no_error_token() {
271+
assert!(Parser::new("foo 4px ( / { !bar }").expect_no_error_token().is_ok());
272+
assert!(Parser::new(")").expect_no_error_token().is_err());
273+
assert!(Parser::new("}").expect_no_error_token().is_err());
274+
assert!(Parser::new("(a){]").expect_no_error_token().is_err());
275+
assert!(Parser::new("'\n'").expect_no_error_token().is_err());
276+
assert!(Parser::new("url('\n'").expect_no_error_token().is_err());
277+
assert!(Parser::new("url(a b)").expect_no_error_token().is_err());
278+
assert!(Parser::new("url(\u{7F})").expect_no_error_token().is_err());
279+
}
280+
281+
269282
fn run_color_tests<F: Fn(Result<Color, ()>) -> Json>(json_data: &str, to_json: F) {
270283
run_json_tests(json_data, |input| {
271284
to_json(input.parse_entirely(Color::parse))

src/tokenizer.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,22 @@ pub enum Token<'a> {
157157
}
158158

159159

160+
impl<'a> Token<'a> {
161+
/// Return whether this token represents a parse error.
162+
///
163+
/// `BadUrl` and `BadString` are tokenizer-level parse errors.
164+
///
165+
/// `CloseParenthesis`, `CloseSquareBracket`, and `CloseCurlyBracket` are *unmatched*
166+
/// and therefore parse errors when returned by one of the `Parser::next*` methods.
167+
pub fn is_parse_error(&self) -> bool {
168+
matches!(
169+
*self,
170+
BadUrl | BadString | CloseParenthesis | CloseSquareBracket | CloseCurlyBracket
171+
)
172+
}
173+
}
174+
175+
160176
/// The numeric value of `Number` and `Dimension` tokens.
161177
#[derive(PartialEq, Debug, Copy, Clone)]
162178
pub struct NumericValue {

0 commit comments

Comments
 (0)