From 8eab8d8131d154dd707d4bf6002330e1c2f250d0 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 16 Mar 2015 20:18:34 -0400 Subject: [PATCH] Migrate `next_*` methods to return `Option` In the Rust standard library, the `next` method on the `Iterator` trait returns an `Option`. Prior to this commit, the `next` and `next_*` methods return `Err<_, ()>`. In an attempt to make some of the code more idiomatic, I migrated these methods to return `Option` instead. --- src/color.rs | 14 ++--- src/nth.rs | 22 +++---- src/parser.rs | 111 +++++++++++++++++----------------- src/rules_and_declarations.rs | 51 ++++++++-------- src/tests.rs | 34 ++++++----- src/tokenizer.rs | 4 +- 6 files changed, 121 insertions(+), 115 deletions(-) diff --git a/src/color.rs b/src/color.rs index 7151fadf..33b991ef 100644 --- a/src/color.rs +++ b/src/color.rs @@ -72,10 +72,10 @@ impl Color { /// /// FIXME(#2) Deprecated CSS2 System Colors are not supported yet. pub fn parse(input: &mut Parser) -> Result { - match try!(input.next()) { - Token::Hash(value) | Token::IDHash(value) => parse_color_hash(&*value), - Token::Ident(value) => parse_color_keyword(&*value), - Token::Function(name) => { + match input.next() { + Some(Token::Hash(value)) | Some(Token::IDHash(value)) => parse_color_hash(&*value), + Some(Token::Ident(value)) => parse_color_keyword(&*value), + Some(Token::Function(name)) => { input.parse_nested_block(|arguments| { parse_color_function(&*name, arguments) }) @@ -307,15 +307,15 @@ fn parse_color_function(name: &str, arguments: &mut Parser) -> Result let blue: f32; if is_rgb { // Either integers or percentages, but all the same type. - match try!(arguments.next()) { - Token::Number(ref v) if v.int_value.is_some() => { + match arguments.next() { + Some(Token::Number(ref v)) if v.int_value.is_some() => { red = (v.value / 255.) as f32; try!(arguments.expect_comma()); green = try!(arguments.expect_integer()) as f32 / 255.; try!(arguments.expect_comma()); blue = try!(arguments.expect_integer()) as f32 / 255.; } - Token::Percentage(ref v) => { + Some(Token::Percentage(ref v)) => { red = v.unit_value as f32; try!(arguments.expect_comma()); green = try!(arguments.expect_percentage()) as f32; diff --git a/src/nth.rs b/src/nth.rs index ddfea493..bea0b1b8 100644 --- a/src/nth.rs +++ b/src/nth.rs @@ -12,9 +12,9 @@ use super::{Token, Parser}; /// 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(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) => { + match input.next() { + Some(Token::Number(value)) => Ok((0, try!(value.int_value.ok_or(())) as i32)), + Some(Token::Dimension(value, unit)) => { let a = try!(value.int_value.ok_or(())) as i32; match_ignore_ascii_case! { unit, "n" => parse_b(input, a), @@ -22,7 +22,7 @@ pub fn parse_nth(input: &mut Parser) -> Result<(i32, i32), ()> { _ => Ok((a, try!(parse_n_dash_digits(&*unit)))) } } - Token::Ident(value) => { + Some(Token::Ident(value)) => { match_ignore_ascii_case! { value, "even" => Ok((2, 0)), "odd" => Ok((2, 1)), @@ -37,8 +37,8 @@ pub fn parse_nth(input: &mut Parser) -> Result<(i32, i32), ()> { } } } - Token::Delim('+') => match try!(input.next_including_whitespace()) { - Token::Ident(value) => { + Some(Token::Delim('+')) => match input.next_including_whitespace() { + Some(Token::Ident(value)) => { match_ignore_ascii_case! { value, "n" => parse_b(input, 1), "n-" => parse_signless_b(input, 1, -1) @@ -55,9 +55,9 @@ pub fn parse_nth(input: &mut Parser) -> Result<(i32, i32), ()> { fn parse_b(input: &mut Parser, a: i32) -> Result<(i32, i32), ()> { let start_position = input.position(); 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.signed => { + Some(Token::Delim('+')) => parse_signless_b(input, a, 1), + Some(Token::Delim('-')) => parse_signless_b(input, a, -1), + Some(Token::Number(ref value)) if value.signed => { Ok((a, try!(value.int_value.ok_or(())) as i32)) } _ => { @@ -68,8 +68,8 @@ fn parse_b(input: &mut Parser, a: i32) -> Result<(i32, i32), ()> { } 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.signed => { + match input.next() { + Some(Token::Number(ref value)) if !value.signed => { Ok((a, b_sign * (try!(value.int_value.ok_or(())) as i32))) } _ => Err(()) diff --git a/src/parser.rs b/src/parser.rs index f195cffe..9c5736db 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -190,10 +190,8 @@ impl<'i, 't> Parser<'i, 't> { pub fn expect_exhausted(&mut self) -> Result<(), ()> { let start_position = self.position(); let result = match self.next() { - Err(()) => Ok(()), - Ok(_) => { - Err(()) - } + None => Ok(()), + Some(_) => Err(()), }; self.reset(start_position); result @@ -270,38 +268,41 @@ 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, ()> { + pub fn next(&mut self) -> Option> { loop { match self.next_including_whitespace_and_comments() { - Ok(Token::WhiteSpace(_)) | Ok(Token::Comment(_)) => {}, + Some(Token::WhiteSpace(_)) | Some(Token::Comment(_)) => {}, result => return result } } } /// Same as `Parser::next`, but does not skip whitespace tokens. - pub fn next_including_whitespace(&mut self) -> Result, ()> { + pub fn next_including_whitespace(&mut self) -> Option> { loop { match self.next_including_whitespace_and_comments() { - Ok(Token::Comment(_)) => {}, + Some(Token::Comment(_)) => {}, result => return result } } } /// Same as `Parser::next`, but does not skip whitespace or comment tokens. - pub fn next_including_whitespace_and_comments(&mut self) -> Result, ()> { + pub fn next_including_whitespace_and_comments(&mut self) -> Option> { if let Some(block_type) = self.at_start_of.take() { consume_until_end_of_block(block_type, &mut *self.tokenizer); } if self.stop_before.contains(Delimiters::from_byte(self.tokenizer.next_byte())) { - return Err(()) + return None } - let token = try!(self.tokenizer.next()); + let token = match self.tokenizer.next() { + Some(t) => t, + None => return None, + }; if let Some(block_type) = BlockType::opening(&token) { self.at_start_of = Some(block_type); } - Ok(token) + Some(token) } /// Have the given closure parse something, then check the the input is exhausted. @@ -333,9 +334,9 @@ impl<'i, 't> Parser<'i, 't> { loop { values.push(try!(self.parse_until_before(Delimiter::Comma, |parser| parse_one(parser)))); match self.next() { - Err(()) => return Ok(values), - Ok(Token::Comma) => continue, - Ok(_) => unreachable!(), + None => return Ok(values), + Some(Token::Comma) => continue, + Some(_) => unreachable!(), } } } @@ -408,7 +409,7 @@ impl<'i, 't> Parser<'i, 't> { if delimiters.contains(Delimiters::from_byte(self.tokenizer.next_byte())) { break } - if let Ok(token) = self.tokenizer.next() { + if let Some(token) = self.tokenizer.next() { if let Some(block_type) = BlockType::opening(&token) { consume_until_end_of_block(block_type, &mut *self.tokenizer); } @@ -440,8 +441,8 @@ impl<'i, 't> Parser<'i, 't> { /// Parse a and return the unescaped value. #[inline] pub fn expect_ident(&mut self) -> Result, ()> { - match try!(self.next()) { - Token::Ident(value) => Ok(value), + match self.next() { + Some(Token::Ident(value)) => Ok(value), _ => Err(()) } } @@ -449,8 +450,8 @@ impl<'i, 't> Parser<'i, 't> { /// Parse a whose unescaped value is an ASCII-insensitive match for the given value. #[inline] pub fn expect_ident_matching<'a>(&mut self, expected_value: &str) -> Result<(), ()> { - match try!(self.next()) { - Token::Ident(ref value) if value.eq_ignore_ascii_case(expected_value) => Ok(()), + match self.next() { + Some(Token::Ident(ref value)) if value.eq_ignore_ascii_case(expected_value) => Ok(()), _ => Err(()) } } @@ -458,8 +459,8 @@ impl<'i, 't> Parser<'i, 't> { /// Parse a and return the unescaped value. #[inline] pub fn expect_string(&mut self) -> Result, ()> { - match try!(self.next()) { - Token::QuotedString(value) => Ok(value), + match self.next() { + Some(Token::QuotedString(value)) => Ok(value), _ => Err(()) } } @@ -467,9 +468,9 @@ impl<'i, 't> Parser<'i, 't> { /// Parse either a or a , and return the unescaped value. #[inline] pub fn expect_ident_or_string(&mut self) -> Result, ()> { - match try!(self.next()) { - Token::Ident(value) => Ok(value), - Token::QuotedString(value) => Ok(value), + match self.next() { + Some(Token::Ident(value)) => Ok(value), + Some(Token::QuotedString(value)) => Ok(value), _ => Err(()) } } @@ -477,8 +478,8 @@ impl<'i, 't> Parser<'i, 't> { /// Parse a and return the unescaped value. #[inline] pub fn expect_url(&mut self) -> Result, ()> { - match try!(self.next()) { - Token::Url(value) => Ok(value), + match self.next() { + Some(Token::Url(value)) => Ok(value), _ => Err(()) } } @@ -486,9 +487,9 @@ impl<'i, 't> Parser<'i, 't> { /// Parse either a or a , and return the unescaped value. #[inline] pub fn expect_url_or_string(&mut self) -> Result, ()> { - match try!(self.next()) { - Token::Url(value) => Ok(value), - Token::QuotedString(value) => Ok(value), + match self.next() { + Some(Token::Url(value)) => Ok(value), + Some(Token::QuotedString(value)) => Ok(value), _ => Err(()) } } @@ -496,8 +497,8 @@ impl<'i, 't> Parser<'i, 't> { /// Parse a and return the integer value. #[inline] pub fn expect_number(&mut self) -> Result { - match try!(self.next()) { - Token::Number(NumericValue { value, .. }) => Ok(value), + match self.next() { + Some(Token::Number(NumericValue { value, .. })) => Ok(value), _ => Err(()) } } @@ -505,8 +506,8 @@ impl<'i, 't> Parser<'i, 't> { /// Parse a that does not have a fractional part, and return the integer value. #[inline] pub fn expect_integer(&mut self) -> Result { - match try!(self.next()) { - Token::Number(NumericValue { int_value, .. }) => int_value.ok_or(()), + match self.next() { + Some(Token::Number(NumericValue { int_value, .. })) => int_value.ok_or(()), _ => Err(()) } } @@ -515,8 +516,8 @@ impl<'i, 't> Parser<'i, 't> { /// `0%` and `100%` map to `0.0` and `1.0` (not `100.0`), respectively. #[inline] pub fn expect_percentage(&mut self) -> Result { - match try!(self.next()) { - Token::Percentage(PercentageValue { unit_value, .. }) => Ok(unit_value), + match self.next() { + Some(Token::Percentage(PercentageValue { unit_value, .. })) => Ok(unit_value), _ => Err(()) } } @@ -524,8 +525,8 @@ impl<'i, 't> Parser<'i, 't> { /// Parse a `:` . #[inline] pub fn expect_colon(&mut self) -> Result<(), ()> { - match try!(self.next()) { - Token::Colon => Ok(()), + match self.next() { + Some(Token::Colon) => Ok(()), _ => Err(()) } } @@ -533,8 +534,8 @@ impl<'i, 't> Parser<'i, 't> { /// Parse a `;` . #[inline] pub fn expect_semicolon(&mut self) -> Result<(), ()> { - match try!(self.next()) { - Token::Semicolon => Ok(()), + match self.next() { + Some(Token::Semicolon) => Ok(()), _ => Err(()) } } @@ -542,8 +543,8 @@ impl<'i, 't> Parser<'i, 't> { /// Parse a `,` . #[inline] pub fn expect_comma(&mut self) -> Result<(), ()> { - match try!(self.next()) { - Token::Comma => Ok(()), + match self.next() { + Some(Token::Comma) => Ok(()), _ => Err(()) } } @@ -551,8 +552,8 @@ impl<'i, 't> Parser<'i, 't> { /// Parse a with the given value. #[inline] pub fn expect_delim(&mut self, expected_value: char) -> Result<(), ()> { - match try!(self.next()) { - Token::Delim(value) if value == expected_value => Ok(()), + match self.next() { + Some(Token::Delim(value)) if value == expected_value => Ok(()), _ => Err(()) } } @@ -562,8 +563,8 @@ 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<(), ()> { - match try!(self.next()) { - Token::CurlyBracketBlock => Ok(()), + match self.next() { + Some(Token::CurlyBracketBlock) => Ok(()), _ => Err(()) } } @@ -573,8 +574,8 @@ 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<(), ()> { - match try!(self.next()) { - Token::SquareBracketBlock => Ok(()), + match self.next() { + Some(Token::SquareBracketBlock) => Ok(()), _ => Err(()) } } @@ -584,8 +585,8 @@ 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<(), ()> { - match try!(self.next()) { - Token::ParenthesisBlock => Ok(()), + match self.next() { + Some(Token::ParenthesisBlock) => Ok(()), _ => Err(()) } } @@ -595,8 +596,8 @@ 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, ()> { - match try!(self.next()) { - Token::Function(name) => Ok(name), + match self.next() { + Some(Token::Function(name)) => Ok(name), _ => Err(()) } } @@ -606,8 +607,8 @@ 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<(), ()> { - match try!(self.next()) { - Token::Function(ref name) if name.eq_ignore_ascii_case(expected_name) => Ok(()), + match self.next() { + Some(Token::Function(ref name)) if name.eq_ignore_ascii_case(expected_name) => Ok(()), _ => Err(()) } } @@ -617,7 +618,7 @@ impl<'i, 't> Parser<'i, 't> { /// Return value indicates whether the end of the input was reached. fn consume_until_end_of_block(block_type: BlockType, tokenizer: &mut Tokenizer) { // FIXME: have a special-purpose tokenizer method for this that does less work. - while let Ok(ref token) = tokenizer.next() { + while let Some(ref token) = tokenizer.next() { if BlockType::closing(token) == Some(block_type) { return } diff --git a/src/rules_and_declarations.rs b/src/rules_and_declarations.rs index fa348f33..18449797 100644 --- a/src/rules_and_declarations.rs +++ b/src/rules_and_declarations.rs @@ -230,8 +230,8 @@ where P: DeclarationParser + AtRuleParser { loop { let start_position = self.input.position(); match self.input.next_including_whitespace_and_comments() { - Ok(Token::WhiteSpace(_)) | Ok(Token::Comment(_)) | Ok(Token::Semicolon) => {} - Ok(Token::Ident(name)) => { + Some(Token::WhiteSpace(_)) | Some(Token::Comment(_)) | Some(Token::Semicolon) => {} + Some(Token::Ident(name)) => { return Some({ let parser = &mut self.parser; self.input.parse_until_after(Delimiter::Semicolon, |input| { @@ -240,14 +240,14 @@ where P: DeclarationParser + AtRuleParser { }) }.map_err(|()| start_position..self.input.position())) } - Ok(Token::AtKeyword(name)) => { + Some(Token::AtKeyword(name)) => { return Some(parse_at_rule(start_position, name, self.input, &mut self.parser)) } - Ok(_) => { + Some(_) => { return Some(self.input.parse_until_after(Delimiter::Semicolon, |_| Err(())) .map_err(|()| start_position..self.input.position())) } - Err(()) => return None, + None => return None, } } } @@ -315,17 +315,17 @@ where P: QualifiedRuleParser + AtRuleParser { loop { let start_position = self.input.position(); match self.input.next_including_whitespace_and_comments() { - Ok(Token::WhiteSpace(_)) | Ok(Token::Comment(_)) => {} - Ok(Token::CDO) | Ok(Token::CDC) if self.is_stylesheet => {} - Ok(Token::AtKeyword(name)) => { + Some(Token::WhiteSpace(_)) | Some(Token::Comment(_)) => {} + Some(Token::CDO) | Some(Token::CDC) if self.is_stylesheet => {} + Some(Token::AtKeyword(name)) => { return Some(parse_at_rule(start_position, name, self.input, &mut self.parser)) } - Ok(_) => { + Some(_) => { self.input.reset(start_position); return Some(parse_qualified_rule(self.input, &mut self.parser) .map_err(|()| start_position..self.input.position())) } - Err(()) => return None, + None => return None, } } } @@ -352,11 +352,12 @@ 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) => { + match input.next_including_whitespace_and_comments() { + Some(Token::WhiteSpace(_)) | Some(Token::Comment(_)) => {} + Some(Token::AtKeyword(name)) => { return parse_at_rule(start_position, name, input, parser).map_err(|_| ()) } + None => return, _ => { input.reset(start_position); return parse_qualified_rule(input, parser).map_err(|_| ()) @@ -378,25 +379,25 @@ fn parse_at_rule

(start_position: SourcePosition, name: Cow, match result { Ok(AtRuleType::WithoutBlock(rule)) => { match input.next() { - Ok(Token::Semicolon) | Err(()) => Ok(rule), - Ok(Token::CurlyBracketBlock) => Err(start_position..input.position()), - Ok(_) => unreachable!() + Some(Token::Semicolon) | None => Ok(rule), + Some(Token::CurlyBracketBlock) => Err(start_position..input.position()), + Some(_) => unreachable!() } } Ok(AtRuleType::WithBlock(prelude)) => { match input.next() { - Ok(Token::CurlyBracketBlock) => { + Some(Token::CurlyBracketBlock) => { input.parse_nested_block(move |input| parser.parse_block(prelude, input)) .map_err(|()| start_position..input.position()) } - Ok(Token::Semicolon) | Err(()) => Err(start_position..input.position()), - Ok(_) => unreachable!() + Some(Token::Semicolon) | None => Err(start_position..input.position()), + Some(_) => unreachable!() } } Ok(AtRuleType::OptionalBlock(prelude)) => { match input.next() { - Ok(Token::Semicolon) | Err(()) => Ok(parser.rule_without_block(prelude)), - Ok(Token::CurlyBracketBlock) => { + Some(Token::Semicolon) | None => Ok(parser.rule_without_block(prelude)), + Some(Token::CurlyBracketBlock) => { input.parse_nested_block(move |input| parser.parse_block(prelude, input)) .map_err(|()| start_position..input.position()) } @@ -406,7 +407,7 @@ fn parse_at_rule

(start_position: SourcePosition, name: Cow, Err(()) => { let end_position = input.position(); match input.next() { - Ok(Token::CurlyBracketBlock) | Ok(Token::Semicolon) | Err(()) => {} + Some(Token::CurlyBracketBlock) | Some(Token::Semicolon) | None => {} _ => unreachable!() } Err(start_position..end_position) @@ -421,12 +422,12 @@ fn parse_qualified_rule

(input: &mut Parser, parser: &mut P) let prelude = input.parse_until_before(Delimiter::CurlyBracketBlock, |input| { parser.parse_prelude(input) }); - match try!(input.next()) { - Token::CurlyBracketBlock => { + match input.next() { + Some(Token::CurlyBracketBlock) => { // Do this here so that we consume the `{` even if the prelude is `Err`. let prelude = try!(prelude); input.parse_nested_block(move |input| parser.parse_block(prelude, input)) } - _ => unreachable!() + _ => Err(()) } } diff --git a/src/tests.rs b/src/tests.rs index c24d15ec..9759841a 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -174,7 +174,11 @@ fn component_value_list() { fn one_component_value() { run_json_tests(include_str!("css-parsing-tests/one_component_value.json"), |input| { input.parse_entirely(|input| { - Ok(one_component_value_to_json(try!(input.next()), input)) + let value = match input.next() { + Some(v) => v, + None => return Err(()), + }; + Ok(one_component_value_to_json(value, input)) }).unwrap_or(JArray!["error", "invalid"]) }); } @@ -311,7 +315,7 @@ fn nth() { fn serializer() { run_json_tests(include_str!("css-parsing-tests/component_value_list.json"), |input| { fn write_to(input: &mut Parser, string: &mut String) { - while let Ok(token) = input.next_including_whitespace_and_comments() { + while let Some(token) = input.next_including_whitespace_and_comments() { token.to_css(string).unwrap(); let closing_token = match token { Token::Function(_) | Token::ParenthesisBlock => Some(Token::CloseParenthesis), @@ -360,35 +364,35 @@ fn serialize_rgba() { fn line_numbers() { let mut input = Parser::new("foo bar\nbaz\r\n\n\"a\\\r\nb\""); assert_eq!(input.current_source_location(), SourceLocation { line: 1, column: 1 }); - assert_eq!(input.next_including_whitespace(), Ok(Token::Ident(Borrowed("foo")))); + assert_eq!(input.next_including_whitespace(), Some(Token::Ident(Borrowed("foo")))); assert_eq!(input.current_source_location(), SourceLocation { line: 1, column: 4 }); - assert_eq!(input.next_including_whitespace(), Ok(Token::WhiteSpace(" "))); + assert_eq!(input.next_including_whitespace(), Some(Token::WhiteSpace(" "))); assert_eq!(input.current_source_location(), SourceLocation { line: 1, column: 5 }); - assert_eq!(input.next_including_whitespace(), Ok(Token::Ident(Borrowed("bar")))); + assert_eq!(input.next_including_whitespace(), Some(Token::Ident(Borrowed("bar")))); assert_eq!(input.current_source_location(), SourceLocation { line: 1, column: 8 }); - assert_eq!(input.next_including_whitespace(), Ok(Token::WhiteSpace("\n"))); + assert_eq!(input.next_including_whitespace(), Some(Token::WhiteSpace("\n"))); assert_eq!(input.current_source_location(), SourceLocation { line: 2, column: 1 }); - assert_eq!(input.next_including_whitespace(), Ok(Token::Ident(Borrowed("baz")))); + assert_eq!(input.next_including_whitespace(), Some(Token::Ident(Borrowed("baz")))); assert_eq!(input.current_source_location(), SourceLocation { line: 2, column: 4 }); let position = input.position(); - assert_eq!(input.next_including_whitespace(), Ok(Token::WhiteSpace("\r\n\n"))); + assert_eq!(input.next_including_whitespace(), Some(Token::WhiteSpace("\r\n\n"))); assert_eq!(input.current_source_location(), SourceLocation { line: 4, column: 1 }); assert_eq!(input.source_location(position), SourceLocation { line: 2, column: 4 }); - assert_eq!(input.next_including_whitespace(), Ok(Token::QuotedString(Borrowed("ab")))); + assert_eq!(input.next_including_whitespace(), Some(Token::QuotedString(Borrowed("ab")))); assert_eq!(input.current_source_location(), SourceLocation { line: 5, column: 3 }); - assert_eq!(input.next_including_whitespace(), Err(())); + assert_eq!(input.next_including_whitespace(), None); } #[test] fn line_delimited() { let mut input = Parser::new(" { foo ; bar } baz;,"); - assert_eq!(input.next(), Ok(Token::CurlyBracketBlock)); + assert_eq!(input.next(), Some(Token::CurlyBracketBlock)); assert_eq!(input.parse_until_after(Delimiter::Semicolon, |_| Ok(42)), Err(())); - assert_eq!(input.next(), Ok(Token::Comma)); - assert_eq!(input.next(), Err(())); + assert_eq!(input.next(), Some(Token::Comma)); + assert_eq!(input.next(), None); } impl ToJson for Color { @@ -414,7 +418,7 @@ impl DeclarationParser for JsonParser { let mut important = false; loop { let start_position = input.position(); - if let Ok(mut token) = input.next_including_whitespace() { + if let Some(mut token) = input.next_including_whitespace() { // Hack to deal with css-parsing-tests assuming that // `!important` in the middle of a declaration value is OK. // This can never happen per spec @@ -487,7 +491,7 @@ impl QualifiedRuleParser for JsonParser { fn component_values_to_json(input: &mut Parser) -> Vec { let mut values = vec![]; - while let Ok(token) = input.next_including_whitespace() { + while let Some(token) = input.next_including_whitespace() { values.push(one_component_value_to_json(token, input)); } values diff --git a/src/tokenizer.rs b/src/tokenizer.rs index a23162a4..b8aee6ce 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -208,8 +208,8 @@ impl<'a> Tokenizer<'a> { } #[inline] - pub fn next(&mut self) -> Result, ()> { - next_token(self).ok_or(()) + pub fn next(&mut self) -> Option> { + next_token(self) } #[inline]