From 0c78da016c95fbda5965556356ca27fe4cc00d11 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 19 Jan 2016 13:05:08 +0100 Subject: [PATCH] Make match_ignore_ascii_case! future-proof. Change the usage syntax to require a comma on the last non-fallback arm, which is a [breaking-change]. The old definition has started to emit a warning in recent nightlies and is likely to be an error in future versions: https://github.com/rust-lang/rfcs/pull/1384 The new definition is recursive to resolve ambiguities. Unfortunately this makes error reporting terrible: https://github.com/rust-lang/rust/issues/31022 --- Cargo.toml | 2 +- src/color.rs | 4 ++-- src/lib.rs | 26 ++++++++++++++++++++------ src/nth.rs | 6 +++--- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 58d812c5..48afdb6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cssparser" -version = "0.4.0" +version = "0.5.0" authors = [ "Simon Sapin " ] description = "Rust implementation of CSS Syntax Level 3" diff --git a/src/color.rs b/src/color.rs index c91b5b7b..d64ca77a 100644 --- a/src/color.rs +++ b/src/color.rs @@ -258,7 +258,7 @@ pub fn parse_color_keyword(ident: &str) -> Result { "yellowgreen" => rgb(154., 205., 50.), "transparent" => Ok(Color::RGBA(RGBA { red: 0., green: 0., blue: 0., alpha: 0. })), - "currentcolor" => Ok(Color::CurrentColor) + "currentcolor" => Ok(Color::CurrentColor), _ => Err(()) } } @@ -312,7 +312,7 @@ fn parse_color_function(name: &str, arguments: &mut Parser) -> Result "rgba" => (true, true), "rgb" => (true, false), "hsl" => (false, false), - "hsla" => (false, true) + "hsla" => (false, true), _ => return Err(()) }; diff --git a/src/lib.rs b/src/lib.rs index c7deb4d4..85803843 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,6 +69,8 @@ fn parse_border_spacing(_context: &ParserContext, input: &mut Parser) */ +#![recursion_limit="200"] // For color::parse_color_keyword + extern crate encoding; #[macro_use] extern crate matches; #[cfg(test)] extern crate tempdir; @@ -99,7 +101,7 @@ Usage example: match_ignore_ascii_case! { string, "foo" => Some(Foo), "bar" => Some(Bar), - "baz" => Some(Baz) + "baz" => Some(Baz), _ => None } ``` @@ -107,13 +109,21 @@ match_ignore_ascii_case! { string, The macro also takes a slice of the value, so that a `String` or `CowString` could be passed directly instead of a `&str`. -Note that because of `macro_rules` ambiguity resolutions quirks, -each arm except the fallback and the one before it must end with a comma. - */ #[macro_export] macro_rules! match_ignore_ascii_case { - ( $value: expr, $( $string: expr => $result: expr ),+ _ => $fallback: expr ) => { + // parse the last case plus the fallback + (@inner $value:expr, ($string:expr => $result:expr, _ => $fallback:expr) -> ($($parsed:tt)*) ) => { + match_ignore_ascii_case!(@inner $value, () -> ($($parsed)* ($string => $result)) $fallback) + }; + + // parse a case (not the last one) + (@inner $value:expr, ($string:expr => $result:expr, $($rest:tt)*) -> ($($parsed:tt)*) ) => { + match_ignore_ascii_case!(@inner $value, ($($rest)*) -> ($($parsed)* ($string => $result))) + }; + + // finished parsing + (@inner $value:expr, () -> ($(($string:expr => $result:expr))*) $fallback:expr ) => { { use std::ascii::AsciiExt; match &$value[..] { @@ -124,8 +134,12 @@ macro_rules! match_ignore_ascii_case { } } }; -} + // entry point, start parsing + ( $value:expr, $($rest:tt)* ) => { + match_ignore_ascii_case!(@inner $value, ($($rest)*) -> ()) + }; +} mod rules_and_declarations; mod tokenizer; diff --git a/src/nth.rs b/src/nth.rs index de0a5358..675f4ba8 100644 --- a/src/nth.rs +++ b/src/nth.rs @@ -18,7 +18,7 @@ pub fn parse_nth(input: &mut Parser) -> Result<(i32, i32), ()> { 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) + "n-" => parse_signless_b(input, a, -1), _ => Ok((a, try!(parse_n_dash_digits(&*unit)))) } } @@ -29,7 +29,7 @@ pub fn parse_nth(input: &mut Parser) -> Result<(i32, i32), ()> { "n" => parse_b(input, 1), "-n" => parse_b(input, -1), "n-" => parse_signless_b(input, 1, -1), - "-n-" => parse_signless_b(input, -1, -1) + "-n-" => parse_signless_b(input, -1, -1), _ => if value.starts_with("-") { Ok((-1, try!(parse_n_dash_digits(&value[1..])))) } else { @@ -41,7 +41,7 @@ pub fn parse_nth(input: &mut Parser) -> Result<(i32, i32), ()> { Token::Ident(value) => { match_ignore_ascii_case! { value, "n" => parse_b(input, 1), - "n-" => parse_signless_b(input, 1, -1) + "n-" => parse_signless_b(input, 1, -1), _ => Ok((1, try!(parse_n_dash_digits(&*value)))) } }