From 8ac1afdd9bb3dc4dab688909102bb2612ce8ff44 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Thu, 18 May 2017 11:25:10 -0400 Subject: [PATCH] Revert "Auto merge of #143 - jdm:parseerror, r=SimonSapin" This reverts commit 0a70d228aca1f60b1d838bbe4b471bfa9c6bb557, reversing changes made to fc0bdcd1845e3aa616c3bdd15127aed259b87cb8. --- Cargo.toml | 2 +- src/color.rs | 86 ++++++++-------- src/lib.rs | 2 +- src/nth.rs | 88 ++++++---------- src/parser.rs | 188 +++++++++++++--------------------- src/rules_and_declarations.rs | 170 +++++++++++------------------- src/tests.rs | 75 +++++--------- src/unicode_range.rs | 17 ++- 8 files changed, 238 insertions(+), 390 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d337b19b..0c618cf8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cssparser" -version = "0.14.0" +version = "0.13.5" authors = [ "Simon Sapin " ] description = "Rust implementation of CSS Syntax Level 3" diff --git a/src/color.rs b/src/color.rs index d0da405c..e716f5e3 100644 --- a/src/color.rs +++ b/src/color.rs @@ -5,7 +5,7 @@ use std::fmt; use std::f32::consts::PI; -use super::{Token, Parser, ToCss, ParseError, BasicParseError}; +use super::{Token, Parser, ToCss}; use tokenizer::NumericValue; #[cfg(feature = "serde")] @@ -141,48 +141,46 @@ impl Color { /// Parse a value, per CSS Color Module Level 3. /// /// FIXME(#2) Deprecated CSS2 System Colors are not supported yet. - pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { - let token = try!(input.next()); - match token { - Token::Hash(ref value) | Token::IDHash(ref value) => { + pub fn parse(input: &mut Parser) -> Result { + match try!(input.next()) { + Token::Hash(value) | Token::IDHash(value) => { Color::parse_hash(value.as_bytes()) }, - Token::Ident(ref value) => parse_color_keyword(&*value), - Token::Function(ref name) => { - return input.parse_nested_block(|arguments| { + Token::Ident(value) => parse_color_keyword(&*value), + Token::Function(name) => { + input.parse_nested_block(|arguments| { parse_color_function(&*name, arguments) - .map_err(|e| ParseError::Basic(e)) - }).map_err(ParseError::<()>::basic); + }) } _ => Err(()) - }.map_err(|()| BasicParseError::UnexpectedToken(token)) + } } /// Parse a color hash, without the leading '#' character. #[inline] pub fn parse_hash(value: &[u8]) -> Result { match value.len() { - 8 => Ok(rgba( + 8 => rgba( try!(from_hex(value[0])) * 16 + try!(from_hex(value[1])), try!(from_hex(value[2])) * 16 + try!(from_hex(value[3])), try!(from_hex(value[4])) * 16 + try!(from_hex(value[5])), - try!(from_hex(value[6])) * 16 + try!(from_hex(value[7]))), + try!(from_hex(value[6])) * 16 + try!(from_hex(value[7])), ), - 6 => Ok(rgb( + 6 => rgb( try!(from_hex(value[0])) * 16 + try!(from_hex(value[1])), try!(from_hex(value[2])) * 16 + try!(from_hex(value[3])), - try!(from_hex(value[4])) * 16 + try!(from_hex(value[5]))), + try!(from_hex(value[4])) * 16 + try!(from_hex(value[5])), ), - 4 => Ok(rgba( + 4 => rgba( try!(from_hex(value[0])) * 17, try!(from_hex(value[1])) * 17, try!(from_hex(value[2])) * 17, - try!(from_hex(value[3])) * 17), + try!(from_hex(value[3])) * 17, ), - 3 => Ok(rgb( + 3 => rgb( try!(from_hex(value[0])) * 17, try!(from_hex(value[1])) * 17, - try!(from_hex(value[2])) * 17), + try!(from_hex(value[2])) * 17, ), _ => Err(()) } @@ -192,13 +190,13 @@ impl Color { #[inline] -fn rgb(red: u8, green: u8, blue: u8) -> Color { +fn rgb(red: u8, green: u8, blue: u8) -> Result { rgba(red, green, blue, 255) } #[inline] -fn rgba(red: u8, green: u8, blue: u8, alpha: u8) -> Color { - Color::RGBA(RGBA::new(red, green, blue, alpha)) +fn rgba(red: u8, green: u8, blue: u8, alpha: u8) -> Result { + Ok(Color::RGBA(RGBA::new(red, green, blue, alpha))) } @@ -412,11 +410,11 @@ fn clamp_floor_256_f32(val: f32) -> u8 { } #[inline] -fn parse_color_function<'i, 't>(name: &str, arguments: &mut Parser<'i, 't>) -> Result> { +fn parse_color_function(name: &str, arguments: &mut Parser) -> Result { let (red, green, blue, uses_commas) = match_ignore_ascii_case! { name, "rgb" | "rgba" => parse_rgb_components_rgb(arguments)?, "hsl" | "hsla" => parse_rgb_components_hsl(arguments)?, - _ => return Err(BasicParseError::UnexpectedToken(Token::Ident(name.to_owned().into()))), + _ => return Err(()) }; let alpha = if !arguments.is_exhausted() { @@ -425,7 +423,7 @@ fn parse_color_function<'i, 't>(name: &str, arguments: &mut Parser<'i, 't>) -> R } else { match try!(arguments.next()) { Token::Delim('/') => {}, - t => return Err(BasicParseError::UnexpectedToken(t)), + _ => return Err(()) }; }; let token = try!(arguments.next()); @@ -436,8 +434,8 @@ fn parse_color_function<'i, 't>(name: &str, arguments: &mut Parser<'i, 't>) -> R Token::Percentage(ref v) => { clamp_unit_f32(v.unit_value) } - t => { - return Err(BasicParseError::UnexpectedToken(t)) + _ => { + return Err(()) } } } else { @@ -445,12 +443,12 @@ fn parse_color_function<'i, 't>(name: &str, arguments: &mut Parser<'i, 't>) -> R }; try!(arguments.expect_exhausted()); - Ok(rgba(red, green, blue, alpha)) + rgba(red, green, blue, alpha) } #[inline] -fn parse_rgb_components_rgb<'i, 't>(arguments: &mut Parser<'i, 't>) -> Result<(u8, u8, u8, bool), BasicParseError<'i>> { +fn parse_rgb_components_rgb(arguments: &mut Parser) -> Result<(u8, u8, u8, bool), ()> { let red: u8; let green: u8; let blue: u8; @@ -467,7 +465,7 @@ fn parse_rgb_components_rgb<'i, 't>(arguments: &mut Parser<'i, 't>) -> Result<(u uses_commas = true; try!(arguments.expect_number()) } - t => return Err(BasicParseError::UnexpectedToken(t)) + _ => return Err(()) }); if uses_commas { try!(arguments.expect_comma()); @@ -482,38 +480,36 @@ fn parse_rgb_components_rgb<'i, 't>(arguments: &mut Parser<'i, 't>) -> Result<(u uses_commas = true; try!(arguments.expect_percentage()) } - t => return Err(BasicParseError::UnexpectedToken(t)) + _ => return Err(()) }); if uses_commas { try!(arguments.expect_comma()); } blue = clamp_unit_f32(try!(arguments.expect_percentage())); } - t => return Err(BasicParseError::UnexpectedToken(t)) + _ => return Err(()) }; return Ok((red, green, blue, uses_commas)); } #[inline] -fn parse_rgb_components_hsl<'i, 't>(arguments: &mut Parser<'i, 't>) -> Result<(u8, u8, u8, bool), BasicParseError<'i>> { +fn parse_rgb_components_hsl(arguments: &mut Parser) -> Result<(u8, u8, u8, bool), ()> { let mut uses_commas = false; // Hue given as an angle // https://drafts.csswg.org/css-values/#angles - let token = try!(arguments.next()); - let hue_degrees = match token { - Token::Number(NumericValue { value: v, .. }) => Ok(v), - Token::Dimension(NumericValue { value: v, .. }, ref unit) => { + let hue_degrees = match try!(arguments.next()) { + Token::Number(NumericValue { value: v, .. }) => v, + Token::Dimension(NumericValue { value: v, .. }, unit) => { match_ignore_ascii_case! { &*unit, - "deg" => Ok(v), - "grad" => Ok(v * 360. / 400.), - "rad" => Ok(v * 360. / (2. * PI)), - "turn" => Ok(v * 360.), - _ => Err(()), + "deg" => v, + "grad" => v * 360. / 400., + "rad" => v * 360. / (2. * PI), + "turn" => v * 360., + _ => return Err(()) } } - t => return Err(BasicParseError::UnexpectedToken(t)) + _ => return Err(()) }; - let hue_degrees = try!(hue_degrees.map_err(|()| BasicParseError::UnexpectedToken(token))); // Subtract an integer before rounding, to avoid some rounding errors: let hue_normalized_degrees = hue_degrees - 360. * (hue_degrees / 360.).floor(); let hue = hue_normalized_degrees / 360.; @@ -526,7 +522,7 @@ fn parse_rgb_components_hsl<'i, 't>(arguments: &mut Parser<'i, 't>) -> Result<(u uses_commas = true; try!(arguments.expect_percentage()) } - t => return Err(BasicParseError::UnexpectedToken(t)) + _ => return Err(()) }; let saturation = saturation.max(0.).min(1.); diff --git a/src/lib.rs b/src/lib.rs index fed095ef..4df99317 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -89,7 +89,7 @@ pub use from_bytes::{stylesheet_encoding, EncodingSupport}; pub use color::{RGBA, Color, parse_color_keyword}; pub use nth::parse_nth; pub use serializer::{ToCss, CssStringWriter, serialize_identifier, serialize_string, TokenSerializationType}; -pub use parser::{Parser, Delimiter, Delimiters, SourcePosition, ParseError, BasicParseError}; +pub use parser::{Parser, Delimiter, Delimiters, SourcePosition}; pub use unicode_range::UnicodeRange; // For macros diff --git a/src/nth.rs b/src/nth.rs index 680ab5aa..ec735bc2 100644 --- a/src/nth.rs +++ b/src/nth.rs @@ -4,98 +4,76 @@ use std::ascii::AsciiExt; -use super::{Token, Parser, BasicParseError}; +use super::{Token, Parser}; /// Parse the *An+B* notation, as found in the `:nth-child()` selector. /// The input is typically the arguments of a function, /// in which case the caller needs to check if the arguments’ parser is exhausted. /// Return `Ok((A, B))`, or `Err(())` for a syntax error. -pub fn parse_nth<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(i32, i32), BasicParseError<'i>> { - let token = try!(input.next()); - match token { - Token::Number(ref value) => { - match value.int_value { - Some(v) => Ok((0, v as i32)), - None => Err(()), +pub fn parse_nth(input: &mut Parser) -> Result<(i32, i32), ()> { + match try!(input.next()) { + Token::Number(value) => Ok((0, try!(value.int_value.ok_or(())) as i32)), + Token::Dimension(value, unit) => { + let a = try!(value.int_value.ok_or(())) as i32; + match_ignore_ascii_case! { &unit, + "n" => parse_b(input, a), + "n-" => parse_signless_b(input, a, -1), + _ => Ok((a, try!(parse_n_dash_digits(&*unit)))) } } - Token::Dimension(value, ref unit) => { - match value.int_value { - Some(v) => { - let a = v as i32; - match_ignore_ascii_case! { - &unit, - "n" => Ok(try!(parse_b(input, a))), - "n-" => Ok(try!(parse_signless_b(input, a, -1))), - _ => { - parse_n_dash_digits(&*unit).map(|val| (a, val)) - } - } - } - None => Err(()), - } - } - Token::Ident(ref value) => { + Token::Ident(value) => { match_ignore_ascii_case! { &value, "even" => Ok((2, 0)), "odd" => Ok((2, 1)), - "n" => Ok(try!(parse_b(input, 1))), - "-n" => Ok(try!(parse_b(input, -1))), - "n-" => Ok(try!(parse_signless_b(input, 1, -1))), - "-n-" => Ok(try!(parse_signless_b(input, -1, -1))), + "n" => parse_b(input, 1), + "-n" => parse_b(input, -1), + "n-" => parse_signless_b(input, 1, -1), + "-n-" => parse_signless_b(input, -1, -1), _ => if value.starts_with("-") { - parse_n_dash_digits(&value[1..]).map(|v| (-1, v)) + Ok((-1, try!(parse_n_dash_digits(&value[1..])))) } else { - parse_n_dash_digits(&*value).map(|v| (1, v)) + Ok((1, try!(parse_n_dash_digits(&*value)))) } } } Token::Delim('+') => match try!(input.next_including_whitespace()) { Token::Ident(value) => { match_ignore_ascii_case! { &value, - "n" => Ok(try!(parse_b(input, 1))), - "n-" => Ok(try!(parse_signless_b(input, 1, -1))), - _ => parse_n_dash_digits(&*value).map(|v| (1, v)) + "n" => parse_b(input, 1), + "n-" => parse_signless_b(input, 1, -1), + _ => Ok((1, try!(parse_n_dash_digits(&*value)))) } } - t => return Err(BasicParseError::UnexpectedToken(t)), + _ => Err(()) }, - _ => Err(()), - }.map_err(|()| BasicParseError::UnexpectedToken(token)) + _ => Err(()) + } } -fn parse_b<'i, 't>(input: &mut Parser<'i, 't>, a: i32) -> Result<(i32, i32), BasicParseError<'i>> { +fn parse_b(input: &mut Parser, a: i32) -> Result<(i32, i32), ()> { let start_position = input.position(); - let token = input.next(); - match token { - Ok(Token::Delim('+')) => Ok(try!(parse_signless_b(input, a, 1))), - Ok(Token::Delim('-')) => Ok(try!(parse_signless_b(input, a, -1))), + match input.next() { + Ok(Token::Delim('+')) => parse_signless_b(input, a, 1), + Ok(Token::Delim('-')) => parse_signless_b(input, a, -1), Ok(Token::Number(ref value)) if value.has_sign => { - match value.int_value { - Some(v) => Ok((a, v as i32)), - None => Err(()), - } + Ok((a, try!(value.int_value.ok_or(())) as i32)) } _ => { input.reset(start_position); Ok((a, 0)) } - }.map_err(|()| BasicParseError::UnexpectedToken(token.unwrap())) + } } -fn parse_signless_b<'i, 't>(input: &mut Parser<'i, 't>, a: i32, b_sign: i32) -> Result<(i32, i32), BasicParseError<'i>> { - let token = try!(input.next()); - match token { +fn parse_signless_b(input: &mut Parser, a: i32, b_sign: i32) -> Result<(i32, i32), ()> { + match try!(input.next()) { Token::Number(ref value) if !value.has_sign => { - match value.int_value { - Some(v) => Ok((a, b_sign * v as i32)), - None => Err(()), - } + Ok((a, b_sign * (try!(value.int_value.ok_or(())) as i32))) } _ => Err(()) - }.map_err(|()| BasicParseError::UnexpectedToken(token)) + } } fn parse_n_dash_digits(string: &str) -> Result { diff --git a/src/parser.rs b/src/parser.rs index 31d11167..9c10ea15 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -21,45 +21,6 @@ pub struct SourcePosition { at_start_of: Option, } -/// The funamental parsing errors that can be triggered by built-in parsing routines. -#[derive(Clone, Debug, PartialEq)] -pub enum BasicParseError<'a> { - /// An unexpected token was encountered. - UnexpectedToken(Token<'a>), - /// A particular token was expected but not found. - ExpectedToken(Token<'a>), - /// The end of the input was encountered unexpectedly. - EndOfInput, - /// An `@` rule was encountered that was invalid. - AtRuleInvalid, - /// A qualified rule was encountered that was invalid. - QualifiedRuleInvalid, -} - -impl<'a, T> From> for ParseError<'a, T> { - fn from(this: BasicParseError<'a>) -> ParseError<'a, T> { - ParseError::Basic(this) - } -} - -/// Extensible parse errors that can be encountered by client parsing implementations. -#[derive(Clone, Debug, PartialEq)] -pub enum ParseError<'a, T: 'a> { - /// A fundamental parse error from a built-in parsing routine. - Basic(BasicParseError<'a>), - /// A parse error reported by downstream consumer code. - Custom(T), -} - -impl<'a, T> ParseError<'a, T> { - /// Extract the fundamental parse error from an extensible error. - pub fn basic(self) -> BasicParseError<'a> { - match self { - ParseError::Basic(e) => e, - ParseError::Custom(_) => panic!("Not a basic parse error"), - } - } -} /// Like std::borrow::Cow, except the borrowed variant contains a mutable /// reference. @@ -227,12 +188,13 @@ impl<'i, 't> Parser<'i, 't> { /// /// This ignores whitespace and comments. #[inline] - pub fn expect_exhausted(&mut self) -> Result<(), BasicParseError<'i>> { + pub fn expect_exhausted(&mut self) -> Result<(), ()> { let start_position = self.position(); let result = match self.next() { - Err(BasicParseError::EndOfInput) => Ok(()), - Err(e) => unreachable!("Unexpected error encountered: {:?}", e), - Ok(t) => Err(BasicParseError::UnexpectedToken(t)), + Err(()) => Ok(()), + Ok(_) => { + Err(()) + } }; self.reset(start_position); result @@ -336,7 +298,7 @@ impl<'i, 't> Parser<'i, 't> { /// See the `Parser::parse_nested_block` method to parse the content of functions or blocks. /// /// This only returns a closing token when it is unmatched (and therefore an error). - pub fn next(&mut self) -> Result, BasicParseError<'i>> { + pub fn next(&mut self) -> Result, ()> { loop { match self.next_including_whitespace_and_comments() { Ok(Token::WhiteSpace(_)) | Ok(Token::Comment(_)) => {}, @@ -346,7 +308,7 @@ impl<'i, 't> Parser<'i, 't> { } /// Same as `Parser::next`, but does not skip whitespace tokens. - pub fn next_including_whitespace(&mut self) -> Result, BasicParseError<'i>> { + pub fn next_including_whitespace(&mut self) -> Result, ()> { loop { match self.next_including_whitespace_and_comments() { Ok(Token::Comment(_)) => {}, @@ -361,15 +323,14 @@ impl<'i, 't> Parser<'i, 't> { /// where comments are preserved. /// When parsing higher-level values, per the CSS Syntax specification, /// comments should always be ignored between tokens. - pub fn next_including_whitespace_and_comments(&mut self) -> Result, BasicParseError<'i>> { + pub fn next_including_whitespace_and_comments(&mut self) -> Result, ()> { if let Some(block_type) = self.at_start_of.take() { consume_until_end_of_block(block_type, &mut *self.tokenizer); } - let byte = self.tokenizer.next_byte(); - if self.stop_before.contains(Delimiters::from_byte(byte)) { - return Err(BasicParseError::EndOfInput) + if self.stop_before.contains(Delimiters::from_byte(self.tokenizer.next_byte())) { + return Err(()) } - let token = try!(self.tokenizer.next().map_err(|()| BasicParseError::EndOfInput)); + let token = try!(self.tokenizer.next()); if let Some(block_type) = BlockType::opening(&token) { self.at_start_of = Some(block_type); } @@ -381,8 +342,8 @@ impl<'i, 't> Parser<'i, 't> { /// /// This can help tell e.g. `color: green;` from `color: green 4px;` #[inline] - pub fn parse_entirely(&mut self, parse: F) -> Result> - where F: FnOnce(&mut Parser<'i, 't>) -> Result> { + pub fn parse_entirely(&mut self, parse: F) -> Result + where F: FnOnce(&mut Parser<'i, 't>) -> Result { let result = parse(self); try!(self.expect_exhausted()); result @@ -399,13 +360,13 @@ impl<'i, 't> Parser<'i, 't> { /// This method retuns `Err(())` the first time that a closure call does, /// or if a closure call leaves some input before the next comma or the end of the input. #[inline] - pub fn parse_comma_separated(&mut self, mut parse_one: F) -> Result, ParseError<'i, E>> - where F: for <'ii, 'tt> FnMut(&mut Parser<'ii, 'tt>) -> Result> { + pub fn parse_comma_separated(&mut self, mut parse_one: F) -> Result, ()> + where F: FnMut(&mut Parser) -> Result { let mut values = vec![]; loop { values.push(try!(self.parse_until_before(Delimiter::Comma, |parser| parse_one(parser)))); match self.next() { - Err(_) => return Ok(values), + Err(()) => return Ok(values), Ok(Token::Comma) => continue, Ok(_) => unreachable!(), } @@ -424,8 +385,8 @@ impl<'i, 't> Parser<'i, 't> { /// /// The result is overridden to `Err(())` if the closure leaves some input before that point. #[inline] - pub fn parse_nested_block(&mut self, parse: F) -> Result > - where F: for<'tt> FnOnce(&mut Parser<'i, 'tt>) -> Result> { + pub fn parse_nested_block(&mut self, parse: F) -> Result + where F: for<'tt> FnOnce(&mut Parser<'i, 'tt>) -> Result { let block_type = self.at_start_of.take().expect("\ A nested parser can only be created when a Function, \ ParenthesisBlock, SquareBracketBlock, or CurlyBracketBlock \ @@ -461,9 +422,9 @@ impl<'i, 't> Parser<'i, 't> { /// /// The result is overridden to `Err(())` if the closure leaves some input before that point. #[inline] - pub fn parse_until_before(&mut self, delimiters: Delimiters, parse: F) - -> Result > - where F: for<'ii, 'tt> FnOnce(&mut Parser<'ii, 'tt>) -> Result> { + pub fn parse_until_before(&mut self, delimiters: Delimiters, parse: F) + -> Result + where F: for<'tt> FnOnce(&mut Parser<'i, 'tt>) -> Result { let delimiters = self.stop_before | delimiters; let result; // Introduce a new scope to limit duration of nested_parser’s borrow @@ -500,9 +461,9 @@ impl<'i, 't> Parser<'i, 't> { /// (e.g. if these is only one in the given set) /// or if it was there at all (as opposed to reaching the end of the input). #[inline] - pub fn parse_until_after(&mut self, delimiters: Delimiters, parse: F) - -> Result > - where F: for<'ii, 'tt> FnOnce(&mut Parser<'ii, 'tt>) -> Result> { + pub fn parse_until_after(&mut self, delimiters: Delimiters, parse: F) + -> Result + where F: for<'tt> FnOnce(&mut Parser<'i, 'tt>) -> Result { let result = self.parse_until_before(delimiters, parse); let next_byte = self.tokenizer.next_byte(); if next_byte.is_some() && !self.stop_before.contains(Delimiters::from_byte(next_byte)) { @@ -517,142 +478,136 @@ impl<'i, 't> Parser<'i, 't> { /// Parse a and return its value. #[inline] - pub fn expect_whitespace(&mut self) -> Result<&'i str, BasicParseError<'i>> { + pub fn expect_whitespace(&mut self) -> Result<&'i str, ()> { match try!(self.next_including_whitespace()) { Token::WhiteSpace(value) => Ok(value), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } /// Parse a and return the unescaped value. #[inline] - pub fn expect_ident(&mut self) -> Result, BasicParseError<'i>> { + pub fn expect_ident(&mut self) -> Result, ()> { match try!(self.next()) { Token::Ident(value) => Ok(value), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } /// Parse a whose unescaped value is an ASCII-insensitive match for the given value. #[inline] - pub fn expect_ident_matching(&mut self, expected_value: &str) -> Result<(), BasicParseError<'i>> { + pub fn expect_ident_matching(&mut self, expected_value: &str) -> Result<(), ()> { match try!(self.next()) { Token::Ident(ref value) if value.eq_ignore_ascii_case(expected_value) => Ok(()), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } /// Parse a and return the unescaped value. #[inline] - pub fn expect_string(&mut self) -> Result, BasicParseError<'i>> { + pub fn expect_string(&mut self) -> Result, ()> { match try!(self.next()) { Token::QuotedString(value) => Ok(value), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } /// Parse either a or a , and return the unescaped value. #[inline] - pub fn expect_ident_or_string(&mut self) -> Result, BasicParseError<'i>> { + pub fn expect_ident_or_string(&mut self) -> Result, ()> { match try!(self.next()) { Token::Ident(value) => Ok(value), Token::QuotedString(value) => Ok(value), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } /// Parse a and return the unescaped value. #[inline] - pub fn expect_url(&mut self) -> Result, BasicParseError<'i>> { + pub fn expect_url(&mut self) -> Result, ()> { match try!(self.next()) { Token::UnquotedUrl(value) => Ok(value), Token::Function(ref name) if name.eq_ignore_ascii_case("url") => { - self.parse_nested_block(|input| input.expect_string() - .map_err(|e| ParseError::Basic(e))) - .map_err(ParseError::<()>::basic) + self.parse_nested_block(|input| input.expect_string()) }, - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } /// Parse either a or a , and return the unescaped value. #[inline] - pub fn expect_url_or_string(&mut self) -> Result, BasicParseError<'i>> { + pub fn expect_url_or_string(&mut self) -> Result, ()> { match try!(self.next()) { Token::UnquotedUrl(value) => Ok(value), Token::QuotedString(value) => Ok(value), Token::Function(ref name) if name.eq_ignore_ascii_case("url") => { - self.parse_nested_block(|input| input.expect_string().map_err(|e| ParseError::Basic(e))) - .map_err(ParseError::<()>::basic) + self.parse_nested_block(|input| input.expect_string()) }, - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } /// Parse a and return the integer value. #[inline] - pub fn expect_number(&mut self) -> Result> { + pub fn expect_number(&mut self) -> Result { match try!(self.next()) { Token::Number(NumericValue { value, .. }) => Ok(value), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } /// Parse a that does not have a fractional part, and return the integer value. #[inline] - pub fn expect_integer(&mut self) -> Result> { - let token = try!(self.next()); - match token { - Token::Number(NumericValue { int_value: Some(int_value), .. }) => { - Ok(int_value) - } - t => Err(BasicParseError::UnexpectedToken(t)) + pub fn expect_integer(&mut self) -> Result { + match try!(self.next()) { + Token::Number(NumericValue { int_value, .. }) => int_value.ok_or(()), + _ => Err(()) } } /// Parse a and return the value. /// `0%` and `100%` map to `0.0` and `1.0` (not `100.0`), respectively. #[inline] - pub fn expect_percentage(&mut self) -> Result> { + pub fn expect_percentage(&mut self) -> Result { match try!(self.next()) { Token::Percentage(PercentageValue { unit_value, .. }) => Ok(unit_value), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } /// Parse a `:` . #[inline] - pub fn expect_colon(&mut self) -> Result<(), BasicParseError<'i>> { + pub fn expect_colon(&mut self) -> Result<(), ()> { match try!(self.next()) { Token::Colon => Ok(()), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } /// Parse a `;` . #[inline] - pub fn expect_semicolon(&mut self) -> Result<(), BasicParseError<'i>> { + pub fn expect_semicolon(&mut self) -> Result<(), ()> { match try!(self.next()) { Token::Semicolon => Ok(()), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } /// Parse a `,` . #[inline] - pub fn expect_comma(&mut self) -> Result<(), BasicParseError<'i>> { + pub fn expect_comma(&mut self) -> Result<(), ()> { match try!(self.next()) { Token::Comma => Ok(()), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } /// Parse a with the given value. #[inline] - pub fn expect_delim(&mut self, expected_value: char) -> Result<(), BasicParseError<'i>> { + pub fn expect_delim(&mut self, expected_value: char) -> Result<(), ()> { match try!(self.next()) { Token::Delim(value) if value == expected_value => Ok(()), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } @@ -660,10 +615,10 @@ impl<'i, 't> Parser<'i, 't> { /// /// If the result is `Ok`, you can then call the `Parser::parse_nested_block` method. #[inline] - pub fn expect_curly_bracket_block(&mut self) -> Result<(), BasicParseError<'i>> { + pub fn expect_curly_bracket_block(&mut self) -> Result<(), ()> { match try!(self.next()) { Token::CurlyBracketBlock => Ok(()), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } @@ -671,10 +626,10 @@ impl<'i, 't> Parser<'i, 't> { /// /// If the result is `Ok`, you can then call the `Parser::parse_nested_block` method. #[inline] - pub fn expect_square_bracket_block(&mut self) -> Result<(), BasicParseError<'i>> { + pub fn expect_square_bracket_block(&mut self) -> Result<(), ()> { match try!(self.next()) { Token::SquareBracketBlock => Ok(()), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } @@ -682,10 +637,10 @@ impl<'i, 't> Parser<'i, 't> { /// /// If the result is `Ok`, you can then call the `Parser::parse_nested_block` method. #[inline] - pub fn expect_parenthesis_block(&mut self) -> Result<(), BasicParseError<'i>> { + pub fn expect_parenthesis_block(&mut self) -> Result<(), ()> { match try!(self.next()) { Token::ParenthesisBlock => Ok(()), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } @@ -693,10 +648,10 @@ impl<'i, 't> Parser<'i, 't> { /// /// If the result is `Ok`, you can then call the `Parser::parse_nested_block` method. #[inline] - pub fn expect_function(&mut self) -> Result, BasicParseError<'i>> { + pub fn expect_function(&mut self) -> Result, ()> { match try!(self.next()) { Token::Function(name) => Ok(name), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } @@ -704,10 +659,10 @@ impl<'i, 't> Parser<'i, 't> { /// /// If the result is `Ok`, you can then call the `Parser::parse_nested_block` method. #[inline] - pub fn expect_function_matching(&mut self, expected_name: &str) -> Result<(), BasicParseError<'i>> { + pub fn expect_function_matching(&mut self, expected_name: &str) -> Result<(), ()> { match try!(self.next()) { Token::Function(ref name) if name.eq_ignore_ascii_case(expected_name) => Ok(()), - t => Err(BasicParseError::UnexpectedToken(t)) + _ => Err(()) } } @@ -715,22 +670,19 @@ impl<'i, 't> Parser<'i, 't> { /// /// See `Token::is_parse_error`. This also checks nested blocks and functions recursively. #[inline] - pub fn expect_no_error_token(&mut self) -> Result<(), BasicParseError<'i>> { + pub fn expect_no_error_token(&mut self) -> Result<(), ()> { loop { match self.next_including_whitespace_and_comments() { Ok(Token::Function(_)) | Ok(Token::ParenthesisBlock) | Ok(Token::SquareBracketBlock) | Ok(Token::CurlyBracketBlock) => { - let result = self.parse_nested_block(|input| input.expect_no_error_token() - .map_err(|e| ParseError::Basic(e))); - try!(result.map_err(ParseError::<()>::basic)) + try!(self.parse_nested_block(|input| input.expect_no_error_token())) } Ok(token) => { if token.is_parse_error() { - //FIXME: maybe these should be separate variants of BasicParseError instead? - return Err(BasicParseError::UnexpectedToken(token)) + return Err(()) } } - Err(_) => return Ok(()) + Err(()) => return Ok(()) } } } diff --git a/src/rules_and_declarations.rs b/src/rules_and_declarations.rs index 5bf102f4..9ccc140e 100644 --- a/src/rules_and_declarations.rs +++ b/src/rules_and_declarations.rs @@ -7,14 +7,14 @@ use std::ascii::AsciiExt; use std::ops::Range; use std::borrow::Cow; -use super::{Token, Parser, Delimiter, SourcePosition, ParseError, BasicParseError}; +use super::{Token, Parser, Delimiter, SourcePosition}; /// Parse `!important`. /// /// Typical usage is `input.try(parse_important).is_ok()` /// at the end of a `DeclarationParser::parse_value` implementation. -pub fn parse_important<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(), BasicParseError<'i>> { +pub fn parse_important(input: &mut Parser) -> Result<(), ()> { try!(input.expect_delim('!')); input.expect_ident_matching("important") } @@ -52,9 +52,6 @@ pub trait DeclarationParser { /// The finished representation of a declaration. type Declaration; - /// The error type that is included in the ParseError value that can be returned. - type Error; - /// Parse the value of a declaration with the given `name`. /// /// Return the finished representation for the declaration @@ -72,8 +69,7 @@ pub trait DeclarationParser { /// If `!important` can be used in a given context, /// `input.try(parse_important).is_ok()` should be used at the end /// of the implementation of this method and the result should be part of the return value. - fn parse_value<'i, 't>(&mut self, name: &str, input: &mut Parser<'i, 't>) - -> Result>; + fn parse_value(&mut self, name: &str, input: &mut Parser) -> Result; } @@ -93,9 +89,6 @@ pub trait AtRuleParser { /// The finished representation of an at-rule. type AtRule; - /// The error type that is included in the ParseError value that can be returned. - type Error; - /// Parse the prelude of an at-rule with the given `name`. /// /// Return the representation of the prelude and the type of at-rule, @@ -113,11 +106,11 @@ pub trait AtRuleParser { /// The given `input` is a "delimited" parser /// that ends wherever the prelude should end. /// (Before the next semicolon, the next `{`, or the end of the current block.) - fn parse_prelude<'i, 't>(&mut self, name: &str, input: &mut Parser<'i, 't>) - -> Result, ParseError<'i, Self::Error>> { + fn parse_prelude(&mut self, name: &str, input: &mut Parser) + -> Result, ()> { let _ = name; let _ = input; - Err(ParseError::Basic(BasicParseError::AtRuleInvalid)) + Err(()) } /// Parse the content of a `{ /* ... */ }` block for the body of the at-rule. @@ -128,11 +121,11 @@ pub trait AtRuleParser { /// /// This is only called when `parse_prelude` returned `WithBlock` or `OptionalBlock`, /// and a block was indeed found following the prelude. - fn parse_block<'i, 't>(&mut self, prelude: Self::Prelude, input: &mut Parser<'i, 't>) - -> Result> { + fn parse_block(&mut self, prelude: Self::Prelude, input: &mut Parser) + -> Result { let _ = prelude; let _ = input; - Err(ParseError::Basic(BasicParseError::AtRuleInvalid)) + Err(()) } /// An `OptionalBlock` prelude was followed by `;`. @@ -164,9 +157,6 @@ pub trait QualifiedRuleParser { /// The finished representation of a qualified rule. type QualifiedRule; - /// The error type that is included in the ParseError value that can be returned. - type Error; - /// Parse the prelude of a qualified rule. For style rules, this is as Selector list. /// /// Return the representation of the prelude, @@ -176,10 +166,9 @@ pub trait QualifiedRuleParser { /// /// The given `input` is a "delimited" parser /// that ends where the prelude should end (before the next `{`). - fn parse_prelude<'i, 't>(&mut self, input: &mut Parser<'i, 't>) - -> Result> { + fn parse_prelude(&mut self, input: &mut Parser) -> Result { let _ = input; - Err(ParseError::Basic(BasicParseError::QualifiedRuleInvalid)) + Err(()) } /// Parse the content of a `{ /* ... */ }` block for the body of the qualified rule. @@ -187,11 +176,11 @@ pub trait QualifiedRuleParser { /// Return the finished representation of the qualified rule /// as returned by `RuleListParser::next`, /// or `Err(())` to ignore the entire at-rule as invalid. - fn parse_block<'i, 't>(&mut self, prelude: Self::Prelude, input: &mut Parser<'i, 't>) - -> Result> { + fn parse_block(&mut self, prelude: Self::Prelude, input: &mut Parser) + -> Result { let _ = prelude; let _ = input; - Err(ParseError::Basic(BasicParseError::QualifiedRuleInvalid)) + Err(()) } } @@ -206,8 +195,8 @@ pub struct DeclarationListParser<'i: 't, 't: 'a, 'a, P> { } -impl<'i, 't, 'a, I, P, E> DeclarationListParser<'i, 't, 'a, P> -where P: DeclarationParser + AtRuleParser { +impl<'i, 't, 'a, I, P> DeclarationListParser<'i, 't, 'a, P> +where P: DeclarationParser + AtRuleParser { /// Create a new `DeclarationListParser` for the given `input` and `parser`. /// /// Note that all CSS declaration lists can on principle contain at-rules. @@ -232,11 +221,11 @@ where P: DeclarationParser + AtRuleParser Iterator for DeclarationListParser<'i, 't, 'a, P> -where P: DeclarationParser + AtRuleParser { - type Item = Result>; +impl<'i, 't, 'a, I, P> Iterator for DeclarationListParser<'i, 't, 'a, P> +where P: DeclarationParser + AtRuleParser { + type Item = Result>; - fn next(&mut self) -> Option>> { + fn next(&mut self) -> Option>> { loop { let start_position = self.input.position(); match self.input.next_including_whitespace_and_comments() { @@ -248,23 +237,16 @@ where P: DeclarationParser + AtRuleParser { return Some(parse_at_rule(start_position, name, self.input, &mut self.parser)) } Ok(_) => { - return Some(self.input.parse_until_after(Delimiter::Semicolon, - |_| Err(ParseError::Basic(BasicParseError::ExpectedToken(Token::Semicolon)))) - .map_err(|e| PreciseParseError { - error: e, - span: start_position..self.input.position() - })) + return Some(self.input.parse_until_after(Delimiter::Semicolon, |_| Err(())) + .map_err(|()| start_position..self.input.position())) } - Err(_) => return None, + Err(()) => return None, } } } @@ -284,8 +266,8 @@ pub struct RuleListParser<'i: 't, 't: 'a, 'a, P> { } -impl<'i: 't, 't: 'a, 'a, R, P, E> RuleListParser<'i, 't, 'a, P> -where P: QualifiedRuleParser + AtRuleParser { +impl<'i: 't, 't: 'a, 'a, R, P> RuleListParser<'i, 't, 'a, P> +where P: QualifiedRuleParser + AtRuleParser { /// Create a new `RuleListParser` for the given `input` at the top-level of a stylesheet /// and the given `parser`. /// @@ -324,11 +306,11 @@ where P: QualifiedRuleParser + AtRuleParser Iterator for RuleListParser<'i, 't, 'a, P> -where P: QualifiedRuleParser + AtRuleParser { - type Item = Result>; +impl<'i, 't, 'a, R, P> Iterator for RuleListParser<'i, 't, 'a, P> +where P: QualifiedRuleParser + AtRuleParser { + type Item = Result>; - fn next(&mut self) -> Option>> { + fn next(&mut self) -> Option>> { loop { let start_position = self.input.position(); match self.input.next_including_whitespace_and_comments() { @@ -339,7 +321,7 @@ where P: QualifiedRuleParser + AtRuleParser> = self.input.parse_until_after(delimiters, |_| Ok(())); + let _ = self.input.parse_until_after(delimiters, |_input| Ok(())); } else { return Some(parse_at_rule(start_position, name, self.input, &mut self.parser)) } @@ -348,12 +330,9 @@ where P: QualifiedRuleParser + AtRuleParser return None, + Err(()) => return None, } } } @@ -361,52 +340,44 @@ where P: QualifiedRuleParser + AtRuleParser(input: &mut Parser<'i, 't>, parser: &mut P) - -> Result<

::Declaration, - PreciseParseError<'i, E>> - where P: DeclarationParser { +pub fn parse_one_declaration

(input: &mut Parser, parser: &mut P) + -> Result<

::Declaration, + Range> + where P: DeclarationParser { let start_position = input.position(); input.parse_entirely(|input| { let name = try!(input.expect_ident()); try!(input.expect_colon()); parser.parse_value(&*name, input) - }).map_err(|e| PreciseParseError { - error: e, - span: start_position..input.position() - }) + }).map_err(|()| start_position..input.position()) } /// Parse a single rule, such as for CSSOM’s `CSSStyleSheet.insertRule`. -pub fn parse_one_rule<'i, 't, R, P, E>(input: &mut Parser<'i, 't>, parser: &mut P) - -> Result> -where P: QualifiedRuleParser + AtRuleParser { +pub fn parse_one_rule(input: &mut Parser, parser: &mut P) -> Result +where P: QualifiedRuleParser + AtRuleParser { input.parse_entirely(|input| { loop { let start_position = input.position(); match try!(input.next_including_whitespace_and_comments()) { Token::WhiteSpace(_) | Token::Comment(_) => {} Token::AtKeyword(name) => { - return parse_at_rule(start_position, name, input, parser).map_err(|e| e.error) + return parse_at_rule(start_position, name, input, parser).map_err(|_| ()) } _ => { input.reset(start_position); - return parse_qualified_rule(input, parser) + return parse_qualified_rule(input, parser).map_err(|_| ()) } } } }) } -pub struct PreciseParseError<'i, E: 'i> { - pub error: ParseError<'i, E>, - pub span: Range, -} -fn parse_at_rule<'i, 't, P, E>(start_position: SourcePosition, name: Cow, - input: &mut Parser<'i, 't>, parser: &mut P) - -> Result<

::AtRule, PreciseParseError<'i, E>> - where P: AtRuleParser { +fn parse_at_rule

(start_position: SourcePosition, name: Cow, + input: &mut Parser, parser: &mut P) + -> Result<

::AtRule, Range> + where P: AtRuleParser { let delimiters = Delimiter::Semicolon | Delimiter::CurlyBracketBlock; let result = input.parse_until_before(delimiters, |input| { parser.parse_prelude(&*name, input) @@ -414,11 +385,8 @@ fn parse_at_rule<'i, 't, P, E>(start_position: SourcePosition, name: Cow, match result { Ok(AtRuleType::WithoutBlock(rule)) => { match input.next() { - Ok(Token::Semicolon) | Err(_) => Ok(rule), - Ok(Token::CurlyBracketBlock) => Err(PreciseParseError { - error: ParseError::Basic(BasicParseError::UnexpectedToken(Token::CurlyBracketBlock)), - span: start_position..input.position(), - }), + Ok(Token::Semicolon) | Err(()) => Ok(rule), + Ok(Token::CurlyBracketBlock) => Err(start_position..input.position()), Ok(_) => unreachable!() } } @@ -426,55 +394,37 @@ fn parse_at_rule<'i, 't, P, E>(start_position: SourcePosition, name: Cow, match input.next() { Ok(Token::CurlyBracketBlock) => { input.parse_nested_block(move |input| parser.parse_block(prelude, input)) - .map_err(|e| PreciseParseError { - error: e, - span: start_position..input.position(), - }) + .map_err(|()| start_position..input.position()) } - Ok(Token::Semicolon) => Err(PreciseParseError { - error: ParseError::Basic(BasicParseError::UnexpectedToken(Token::Semicolon)), - span: start_position..input.position() - }), - Err(e) => Err(PreciseParseError { - error: ParseError::Basic(e), - span: start_position..input.position(), - }), + Ok(Token::Semicolon) | Err(()) => Err(start_position..input.position()), Ok(_) => unreachable!() } } Ok(AtRuleType::OptionalBlock(prelude)) => { match input.next() { - Ok(Token::Semicolon) | Err(_) => Ok(parser.rule_without_block(prelude)), + Ok(Token::Semicolon) | Err(()) => Ok(parser.rule_without_block(prelude)), Ok(Token::CurlyBracketBlock) => { input.parse_nested_block(move |input| parser.parse_block(prelude, input)) - .map_err(|e| PreciseParseError { - error: e, - span: start_position..input.position(), - }) + .map_err(|()| start_position..input.position()) } _ => unreachable!() } } - Err(_) => { + Err(()) => { let end_position = input.position(); - let error = match input.next() { - Ok(Token::CurlyBracketBlock) => BasicParseError::UnexpectedToken(Token::CurlyBracketBlock), - Ok(Token::Semicolon) => BasicParseError::UnexpectedToken(Token::Semicolon), - Err(e) => e, + match input.next() { + Ok(Token::CurlyBracketBlock) | Ok(Token::Semicolon) | Err(()) => {} _ => unreachable!() - }; - Err(PreciseParseError { - error: ParseError::Basic(error), - span: start_position..end_position, - }) + } + Err(start_position..end_position) } } } -fn parse_qualified_rule<'i, 't, P, E>(input: &mut Parser<'i, 't>, parser: &mut P) - -> Result<

::QualifiedRule, ParseError<'i, E>> - where P: QualifiedRuleParser { +fn parse_qualified_rule

(input: &mut Parser, parser: &mut P) + -> Result<

::QualifiedRule, ()> + where P: QualifiedRuleParser { let prelude = input.parse_until_before(Delimiter::CurlyBracketBlock, |input| { parser.parse_prelude(input) }); diff --git a/src/tests.rs b/src/tests.rs index fee8df18..e10b1df1 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -12,8 +12,8 @@ use rustc_serialize::json::{self, Json, ToJson}; #[cfg(feature = "bench")] use self::test::Bencher; -use super::{Parser, Delimiter, Token, NumericValue, PercentageValue, SourceLocation, ParseError, - DeclarationListParser, DeclarationParser, RuleListParser, BasicParseError, +use super::{Parser, Delimiter, Token, NumericValue, PercentageValue, SourceLocation, + DeclarationListParser, DeclarationParser, RuleListParser, AtRuleType, AtRuleParser, QualifiedRuleParser, parse_one_declaration, parse_one_rule, parse_important, stylesheet_encoding, EncodingSupport, @@ -117,10 +117,9 @@ fn component_value_list() { #[test] fn one_component_value() { run_json_tests(include_str!("css-parsing-tests/one_component_value.json"), |input| { - let result: Result> = input.parse_entirely(|input| { + input.parse_entirely(|input| { Ok(one_component_value_to_json(try!(input.next()), input)) - }); - result.unwrap_or(JArray!["error", "invalid"]) + }).unwrap_or(JArray!["error", "invalid"]) }); } @@ -252,13 +251,9 @@ fn expect_no_error_token() { fn outer_block_end_consumed() { let mut input = Parser::new("(calc(true))"); assert!(input.expect_parenthesis_block().is_ok()); - assert!(input.parse_nested_block(|input| { - let result: Result<_, ParseError<()>> = input.expect_function_matching("calc") - .map_err(|e| ParseError::Basic(e)); - result - }).is_ok()); + assert!(input.parse_nested_block(|input| input.expect_function_matching("calc")).is_ok()); println!("{:?}", input.position()); - assert!(input.next().is_err()); + assert_eq!(input.next(), Err(())); } #[test] @@ -283,7 +278,7 @@ fn unquoted_url_escaping() { #[test] fn test_expect_url() { - fn parse(s: &str) -> Result, BasicParseError> { + fn parse(s: &str) -> Result, ()> { Parser::new(s).expect_url() } assert_eq!(parse("url()").unwrap(), ""); @@ -291,19 +286,16 @@ fn test_expect_url() { assert_eq!(parse("url( abc").unwrap(), "abc"); assert_eq!(parse("url( abc \t)").unwrap(), "abc"); assert_eq!(parse("url( 'abc' \t)").unwrap(), "abc"); - assert!(parse("url(abc more stuff)").is_err()); + assert_eq!(parse("url(abc more stuff)"), Err(())); // The grammar at https://drafts.csswg.org/css-values/#urls plans for `*` // at the position of "more stuff", but no such modifier is defined yet. - assert!(parse("url('abc' more stuff)").is_err()); + assert_eq!(parse("url('abc' more stuff)"), Err(())); } fn run_color_tests) -> Json>(json_data: &str, to_json: F) { run_json_tests(json_data, |input| { - let result: Result<_, ParseError<()>> = input.parse_entirely(|i| { - Color::parse(i).map_err(|e| ParseError::Basic(e)) - }); - to_json(result.map_err(|_| ())) + to_json(input.parse_entirely(Color::parse)) }); } @@ -330,17 +322,14 @@ fn color3_keywords() { #[test] fn nth() { run_json_tests(include_str!("css-parsing-tests/An+B.json"), |input| { - input.parse_entirely(|i| { - let result: Result<_, ParseError<()>> = parse_nth(i).map_err(|e| ParseError::Basic(e)); - result - }).ok().to_json() + input.parse_entirely(parse_nth).ok().to_json() }); } #[test] fn unicode_range() { run_json_tests(include_str!("css-parsing-tests/urange.json"), |input| { - let result: Result<_, ParseError<()>> = input.parse_comma_separated(|input| { + input.parse_comma_separated(|input| { let result = UnicodeRange::parse(input).ok().map(|r| (r.start, r.end)); if input.is_exhausted() { Ok(result) @@ -348,8 +337,7 @@ fn unicode_range() { while let Ok(_) = input.next() {} Ok(None) } - }); - result.unwrap().to_json() + }).unwrap().to_json() }); } @@ -388,11 +376,10 @@ fn serializer(preserve_comments: bool) { _ => None }; if let Some(closing_token) = closing_token { - let result: Result<_, ParseError<()>> = input.parse_nested_block(|input| { + input.parse_nested_block(|input| { write_to(previous_token, input, string, preserve_comments); Ok(()) - }); - result.unwrap(); + }).unwrap(); closing_token.to_css(string).unwrap(); } } @@ -451,7 +438,7 @@ fn line_numbers() { assert_eq!(input.next_including_whitespace(), Ok(Token::QuotedString(Borrowed("ab")))); assert_eq!(input.current_source_location(), SourceLocation { line: 5, column: 3 }); - assert!(input.next_including_whitespace().is_err()); + assert_eq!(input.next_including_whitespace(), Err(())); } #[test] @@ -514,12 +501,9 @@ fn overflow() { fn line_delimited() { let mut input = Parser::new(" { foo ; bar } baz;,"); assert_eq!(input.next(), Ok(Token::CurlyBracketBlock)); - assert!({ - let result: Result<_, ParseError<()>> = input.parse_until_after(Delimiter::Semicolon, |_| Ok(42)); - result - }.is_err()); + assert_eq!(input.parse_until_after(Delimiter::Semicolon, |_| Ok(42)), Err(())); assert_eq!(input.next(), Ok(Token::Comma)); - assert!(input.next().is_err()); + assert_eq!(input.next(), Err(())); } #[test] @@ -651,10 +635,8 @@ fn no_stack_overflow_multiple_nested_blocks() { impl DeclarationParser for JsonParser { type Declaration = Json; - type Error = (); - fn parse_value<'i, 't>(&mut self, name: &str, input: &mut Parser<'i, 't>) - -> Result> { + fn parse_value(&mut self, name: &str, input: &mut Parser) -> Result { let mut value = vec![]; let mut important = false; loop { @@ -692,10 +674,9 @@ impl DeclarationParser for JsonParser { impl AtRuleParser for JsonParser { type Prelude = Vec; type AtRule = Json; - type Error = (); - fn parse_prelude<'i, 't>(&mut self, name: &str, input: &mut Parser<'i, 't>) - -> Result, Json>, ParseError<'i, ()>> { + fn parse_prelude(&mut self, name: &str, input: &mut Parser) + -> Result, Json>, ()> { Ok(AtRuleType::OptionalBlock(vec![ "at-rule".to_json(), name.to_json(), @@ -703,8 +684,7 @@ impl AtRuleParser for JsonParser { ])) } - fn parse_block<'i, 't>(&mut self, mut prelude: Vec, input: &mut Parser<'i, 't>) - -> Result> { + fn parse_block(&mut self, mut prelude: Vec, input: &mut Parser) -> Result { prelude.push(Json::Array(component_values_to_json(input))); Ok(Json::Array(prelude)) } @@ -718,14 +698,12 @@ impl AtRuleParser for JsonParser { impl QualifiedRuleParser for JsonParser { type Prelude = Vec; type QualifiedRule = Json; - type Error = (); - fn parse_prelude<'i, 't>(&mut self, input: &mut Parser<'i, 't>) -> Result, ParseError<'i, ()>> { + fn parse_prelude(&mut self, input: &mut Parser) -> Result, ()> { Ok(component_values_to_json(input)) } - fn parse_block<'i, 't>(&mut self, prelude: Vec, input: &mut Parser<'i, 't>) - -> Result> { + fn parse_block(&mut self, prelude: Vec, input: &mut Parser) -> Result { Ok(JArray![ "qualified rule", prelude, @@ -752,10 +730,7 @@ fn one_component_value_to_json(token: Token, input: &mut Parser) -> Json { } fn nested(input: &mut Parser) -> Vec { - let result: Result<_, ParseError<()>> = input.parse_nested_block(|input| { - Ok(component_values_to_json(input)) - }); - result.unwrap() + input.parse_nested_block(|input| Ok(component_values_to_json(input))).unwrap() } match token { diff --git a/src/unicode_range.rs b/src/unicode_range.rs index 64030358..6a6dc022 100644 --- a/src/unicode_range.rs +++ b/src/unicode_range.rs @@ -4,7 +4,7 @@ //! https://drafts.csswg.org/css-syntax/#urange -use {Parser, ToCss, BasicParseError}; +use {Parser, ToCss}; use std::char; use std::cmp; use std::fmt; @@ -24,7 +24,7 @@ pub struct UnicodeRange { impl UnicodeRange { /// https://drafts.csswg.org/css-syntax/#urange-syntax - pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result> { + pub fn parse(input: &mut Parser) -> Result { // = // u '+' '?'* | // u '?'* | @@ -42,25 +42,22 @@ impl UnicodeRange { // but oh well… let concatenated_tokens = input.slice_from(after_u); - let range = match parse_concatenated(concatenated_tokens.as_bytes()) { - Ok(range) => range, - Err(()) => return Err(BasicParseError::UnexpectedToken(Token::Ident(concatenated_tokens.into()))), - }; + let range = parse_concatenated(concatenated_tokens.as_bytes())?; if range.end > char::MAX as u32 || range.start > range.end { - Err(BasicParseError::UnexpectedToken(Token::Ident(concatenated_tokens.into()))) + Err(()) } else { Ok(range) } } } -fn parse_tokens<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(), BasicParseError<'i>> { +fn parse_tokens(input: &mut Parser) -> Result<(), ()> { match input.next_including_whitespace()? { Token::Delim('+') => { match input.next_including_whitespace()? { Token::Ident(_) => {} Token::Delim('?') => {} - t => return Err(BasicParseError::UnexpectedToken(t)) + _ => return Err(()) } parse_question_marks(input) } @@ -76,7 +73,7 @@ fn parse_tokens<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(), BasicParseErro _ => input.reset(after_number) } } - t => return Err(BasicParseError::UnexpectedToken(t)) + _ => return Err(()) } Ok(()) }