From 8ff0c64b6240e595ae99268a16c1b41bac7eee91 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 9 May 2014 16:53:26 +0100 Subject: [PATCH] Upgrade to Rust aa67254 2014-05-08 --- .gitignore | 1 + ast.rs | 43 +++++++++--------- color.rs | 7 +-- from_bytes.rs | 6 +-- nth.rs | 2 +- parser.rs | 18 ++++---- serializer.rs | 28 ++++++------ tests.rs | 118 ++++++++++++++++++++++++++------------------------ tokenizer.rs | 58 ++++++++++++------------- 9 files changed, 144 insertions(+), 137 deletions(-) diff --git a/.gitignore b/.gitignore index f646df45..1500b0d1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.o *.a *.so +*.rlib *.dylib *.dSYM *.dll diff --git a/ast.rs b/ast.rs index 75b26d48..c76289d1 100644 --- a/ast.rs +++ b/ast.rs @@ -4,11 +4,12 @@ use std::fmt; use std::slice; +use std::vec; #[deriving(Eq)] pub struct NumericValue { - pub representation: ~str, + pub representation: StrBuf, pub value: f64, pub int_value: Option, } @@ -27,16 +28,16 @@ pub type Node = (ComponentValue, SourceLocation); // TODO this is not a good na #[deriving(Eq)] pub enum ComponentValue { // Preserved tokens. - Ident(~str), - AtKeyword(~str), - Hash(~str), - IDHash(~str), // Hash that is a valid ID selector. - String(~str), - URL(~str), + Ident(StrBuf), + AtKeyword(StrBuf), + Hash(StrBuf), + IDHash(StrBuf), // Hash that is a valid ID selector. + String(StrBuf), + URL(StrBuf), Delim(char), Number(NumericValue), Percentage(NumericValue), - Dimension(NumericValue, ~str), + Dimension(NumericValue, StrBuf), UnicodeRange(u32, u32), // (start, end) of range WhiteSpace, Colon, // : @@ -52,12 +53,12 @@ pub enum ComponentValue { CDC, // --> // Function - Function(~str, ~[ComponentValue]), // name, arguments + Function(StrBuf, Vec), // name, arguments // Simple block - ParenthesisBlock(~[ComponentValue]), // (…) - SquareBracketBlock(~[ComponentValue]), // […] - CurlyBracketBlock(~[Node]), // {…} + ParenthesisBlock(Vec), // (…) + SquareBracketBlock(Vec), // […] + CurlyBracketBlock(Vec), // {…} // These are always invalid BadURL, @@ -71,24 +72,24 @@ pub enum ComponentValue { #[deriving(Eq)] pub struct Declaration { pub location: SourceLocation, - pub name: ~str, - pub value: ~[ComponentValue], + pub name: StrBuf, + pub value: Vec, pub important: bool, } #[deriving(Eq)] pub struct QualifiedRule { pub location: SourceLocation, - pub prelude: ~[ComponentValue], - pub block: ~[Node], + pub prelude: Vec, + pub block: Vec, } #[deriving(Eq)] pub struct AtRule { pub location: SourceLocation, - pub name: ~str, - pub prelude: ~[ComponentValue], - pub block: Option<~[Node]>, + pub name: StrBuf, + pub prelude: Vec, + pub block: Option>, } #[deriving(Eq)] @@ -156,14 +157,14 @@ pub trait MoveSkipWhitespaceIterable { fn move_skip_whitespace(self) -> MoveSkipWhitespaceIterator; } -impl MoveSkipWhitespaceIterable for ~[ComponentValue] { +impl MoveSkipWhitespaceIterable for Vec { fn move_skip_whitespace(self) -> MoveSkipWhitespaceIterator { MoveSkipWhitespaceIterator{ iter_with_whitespace: self.move_iter() } } } pub struct MoveSkipWhitespaceIterator { - iter_with_whitespace: slice::MoveItems, + iter_with_whitespace: vec::MoveItems, } impl Iterator for MoveSkipWhitespaceIterator { diff --git a/color.rs b/color.rs index 4b9debce..0cd3debd 100644 --- a/color.rs +++ b/color.rs @@ -28,9 +28,10 @@ pub enum Color { impl Color { pub fn parse(component_value: &ComponentValue) -> Option { match *component_value { - Hash(ref value) | IDHash(ref value) => parse_color_hash(*value), - Ident(ref value) => parse_color_keyword(*value), - Function(ref name, ref arguments) => parse_color_function(*name, *arguments), + Hash(ref value) | IDHash(ref value) => parse_color_hash(value.as_slice()), + Ident(ref value) => parse_color_keyword(value.as_slice()), + Function(ref name, ref arguments) + => parse_color_function(name.as_slice(), arguments.as_slice()), _ => None } } diff --git a/from_bytes.rs b/from_bytes.rs index bc0de828..1400df44 100644 --- a/from_bytes.rs +++ b/from_bytes.rs @@ -33,7 +33,7 @@ use parser::{parse_stylesheet_rules, StylesheetParser}; /// and the `Encoding` object that was used. pub fn decode_stylesheet_bytes(css: &[u8], protocol_encoding_label: Option<&str>, environment_encoding: Option) - -> (~str, EncodingRef) { + -> (StrBuf, EncodingRef) { // http://dev.w3.org/csswg/css-syntax/#the-input-byte-stream match protocol_encoding_label { None => (), @@ -71,7 +71,7 @@ pub fn decode_stylesheet_bytes(css: &[u8], protocol_encoding_label: Option<&str> #[inline] -fn decode_replace(input: &[u8], fallback_encoding: EncodingRef)-> (~str, EncodingRef) { +fn decode_replace(input: &[u8], fallback_encoding: EncodingRef)-> (StrBuf, EncodingRef) { let (result, used_encoding) = decode(input, DecodeReplace, fallback_encoding); (result.unwrap(), used_encoding) } @@ -97,5 +97,5 @@ pub fn parse_stylesheet_rules_from_bytes( -> (StylesheetParser, EncodingRef) { let (css_unicode, encoding) = decode_stylesheet_bytes( css_bytes, protocol_encoding_label, environment_encoding); - (parse_stylesheet_rules(tokenize(css_unicode)), encoding) + (parse_stylesheet_rules(tokenize(css_unicode.as_slice())), encoding) } diff --git a/nth.rs b/nth.rs index 7422e381..fddb13b5 100644 --- a/nth.rs +++ b/nth.rs @@ -116,7 +116,7 @@ fn parse_n_dash_digits(string: &str) -> Option { #[inline] fn has_sign(value: &NumericValue) -> bool { - match value.representation[0] as char { + match value.representation.as_bytes()[0] as char { '+' | '-' => true, _ => false } diff --git a/parser.rs b/parser.rs index f89e2c7c..4cd2a81f 100644 --- a/parser.rs +++ b/parser.rs @@ -20,9 +20,9 @@ use std::ascii::StrAsciiExt; use ast::*; -pub struct StylesheetParser{ priv iter: T } -pub struct RuleListParser{ priv iter: T } -pub struct DeclarationListParser{ priv iter: T } +pub struct StylesheetParser{ iter: T } +pub struct RuleListParser{ iter: T } +pub struct DeclarationListParser{ iter: T } /// Parse top-level of a CSS stylesheet. /// Return a Iterator> @@ -173,9 +173,9 @@ for DeclarationListParser { } -fn parse_at_rule>(iter: &mut T, name: ~str, location: SourceLocation) +fn parse_at_rule>(iter: &mut T, name: StrBuf, location: SourceLocation) -> AtRule { - let mut prelude = ~[]; + let mut prelude = Vec::new(); let mut block = None; for_iter!(iter, (component_value, _location), { match component_value { @@ -193,10 +193,10 @@ fn parse_qualified_rule>(iter: &mut T, first: ComponentValue, -> Result { match first { CurlyBracketBlock(content) - => return Ok(QualifiedRule { location: location, prelude: ~[], block: content }), + => return Ok(QualifiedRule { location: location, prelude: Vec::new(), block: content }), _ => (), } - let mut prelude = ~[first]; + let mut prelude = vec!(first); for_iter!(iter, (component_value, _location), { match component_value { CurlyBracketBlock(content) @@ -219,7 +219,7 @@ fn parse_declaration>(iter: &mut T, first: ComponentValue, Some((Colon, _)) => (), _ => return error(location, ErrInvalidDeclarationSyntax), } - let mut value = ~[]; + let mut value = Vec::new(); let mut important = false; for_iter!(iter, (component_value, _location), { match component_value { @@ -243,7 +243,7 @@ fn parse_declaration_important>(iter: &mut T) -> bool { Some((Ident(value), _)) => value, _ => return false, }; - if !ident_value.eq_ignore_ascii_case("important") { return false } + if !ident_value.as_slice().eq_ignore_ascii_case("important") { return false } match next_non_whitespace(iter) { Some((Semicolon, _)) => true, None => true, diff --git a/serializer.rs b/serializer.rs index 3a788506..561462a4 100644 --- a/serializer.rs +++ b/serializer.rs @@ -7,13 +7,13 @@ use ast::*; impl ast::ComponentValue { - pub fn to_css(&mut self) -> ~str { - let mut css = ~""; + pub fn to_css(&mut self) -> StrBuf { + let mut css = StrBuf::new(); self.to_css_push(&mut css); css } - pub fn to_css_push(&self, css: &mut ~str) { + pub fn to_css_push(&self, css: &mut StrBuf) { match *self { Ident(ref value) => serialize_identifier(value.as_slice(), css), AtKeyword(ref value) => { @@ -22,7 +22,7 @@ impl ast::ComponentValue { }, Hash(ref value) => { css.push_char('#'); - for c in value.chars() { + for c in value.as_slice().chars() { serialize_char(c, css, /* is_identifier_start = */ false); } }, @@ -38,13 +38,13 @@ impl ast::ComponentValue { }, Delim(value) => css.push_char(value), - Number(ref value) => css.push_str(value.representation), + Number(ref value) => css.push_str(value.representation.as_slice()), Percentage(ref value) => { - css.push_str(value.representation); + css.push_str(value.representation.as_slice()); css.push_char('%'); }, Dimension(ref value, ref unit) => { - css.push_str(value.representation); + css.push_str(value.representation.as_slice()); // Disambiguate with scientific notation. let unit = unit.as_slice(); if unit == "e" || unit == "E" || unit.starts_with("e-") || unit.starts_with("E-") { @@ -109,7 +109,7 @@ impl ast::ComponentValue { } -pub fn serialize_identifier(value: &str, css: &mut ~str) { +pub fn serialize_identifier(value: &str, css: &mut StrBuf) { // TODO: avoid decoding/re-encoding UTF-8? let mut iter = value.chars(); let mut c = iter.next().unwrap(); @@ -127,7 +127,7 @@ pub fn serialize_identifier(value: &str, css: &mut ~str) { #[inline] -fn serialize_char(c: char, css: &mut ~str, is_identifier_start: bool) { +fn serialize_char(c: char, css: &mut StrBuf, is_identifier_start: bool) { match c { '0'..'9' if is_identifier_start => css.push_str(format!("\\\\3{} ", c)), '-' if is_identifier_start => css.push_str("\\-"), @@ -141,7 +141,7 @@ fn serialize_char(c: char, css: &mut ~str, is_identifier_start: bool) { } -pub fn serialize_string(value: &str, css: &mut ~str) { +pub fn serialize_string(value: &str, css: &mut StrBuf) { css.push_char('"'); // TODO: avoid decoding/re-encoding UTF-8? for c in value.chars() { @@ -159,18 +159,18 @@ pub fn serialize_string(value: &str, css: &mut ~str) { pub trait ToCss { - fn to_css(&mut self) -> ~str { - let mut css = ~""; + fn to_css(&mut self) -> StrBuf { + let mut css = StrBuf::new(); self.to_css_push(&mut css); css } - fn to_css_push(&mut self, css: &mut ~str); + fn to_css_push(&mut self, css: &mut StrBuf); } impl<'a, I: Iterator<&'a ComponentValue>> ToCss for I { - fn to_css_push(&mut self, css: &mut ~str) { + fn to_css_push(&mut self, css: &mut StrBuf) { let mut previous = match self.next() { None => return, Some(first) => { first.to_css_push(css); first } diff --git a/tests.rs b/tests.rs index aaa27836..6ce1cca4 100644 --- a/tests.rs +++ b/tests.rs @@ -13,6 +13,10 @@ use encoding::label::encoding_from_whatwg_label; use super::*; use ast::*; +macro_rules! JString { + ($e: expr) => { json::String($e.to_owned()) } +} + fn write_whole_file(path: &Path, data: &str) { match File::open_mode(path, io::Open, io::Write) { @@ -29,7 +33,7 @@ fn almost_equals(a: &json::Json, b: &json::Json) -> bool { (&json::Boolean(a), &json::Boolean(b)) => a == b, (&json::List(ref a), &json::List(ref b)) => a.iter().zip(b.iter()).all(|(ref a, ref b)| almost_equals(*a, *b)), - (&json::Object(_), &json::Object(_)) => fail!(~"Not implemented"), + (&json::Object(_), &json::Object(_)) => fail!("Not implemented"), (&json::Null, &json::Null) => true, _ => false, } @@ -50,7 +54,8 @@ fn assert_json_eq(results: json::Json, expected: json::Json, message: ~str) { write_whole_file(&expected_path, expected); Process::status( "colordiff", - [~"-u1000", result_path.display().to_str(), expected_path.display().to_str()] + ["-u1000".to_owned(), result_path.display().to_str(), + expected_path.display().to_str()] ).unwrap(); }).unwrap(); @@ -157,12 +162,12 @@ fn stylesheet_from_bytes() { }; let result = { - let css = get_string(map, &~"css_bytes").unwrap().chars().map(|c| { + let css = get_string(map, &"css_bytes".to_owned()).unwrap().chars().map(|c| { assert!(c as u32 <= 0xFF); c as u8 }).collect::<~[u8]>(); - let protocol_encoding_label = get_string(map, &~"protocol_encoding"); - let environment_encoding = get_string(map, &~"environment_encoding") + let protocol_encoding_label = get_string(map, &"protocol_encoding".to_owned()); + let environment_encoding = get_string(map, &"environment_encoding".to_owned()) .and_then(encoding_from_whatwg_label); let (mut rules, used_encoding) = parse_stylesheet_rules_from_bytes( @@ -213,7 +218,7 @@ fn color3_keywords() { match c { Some(RGBA(RGBA { red: r, green: g, blue: b, alpha: a })) => (~[r * 255., g * 255., b * 255., a]).to_json(), - Some(CurrentColor) => json::String(~"currentColor"), + Some(CurrentColor) => JString!("currentColor"), None => json::Null, } }); @@ -221,21 +226,21 @@ fn color3_keywords() { #[bench] -fn bench_color_lookup_red(b: &mut test::BenchHarness) { +fn bench_color_lookup_red(b: &mut test::Bencher) { let ident = parse_one_component_value(tokenize("red")).unwrap(); b.iter(|| assert!(Color::parse(&ident).is_some())); } #[bench] -fn bench_color_lookup_lightgoldenrodyellow(b: &mut test::BenchHarness) { +fn bench_color_lookup_lightgoldenrodyellow(b: &mut test::Bencher) { let ident = parse_one_component_value(tokenize("lightgoldenrodyellow")).unwrap(); b.iter(|| assert!(Color::parse(&ident).is_some())); } #[bench] -fn bench_color_lookup_fail(b: &mut test::BenchHarness) { +fn bench_color_lookup_fail(b: &mut test::Bencher) { let ident = parse_one_component_value(tokenize("lightgoldenrodyellowbazinga")).unwrap(); b.iter(|| assert!(Color::parse(&ident).is_none())); } @@ -254,7 +259,7 @@ fn serializer() { run_json_tests(include_str!("css-parsing-tests/component_value_list.json"), |input| { let component_values = tokenize(input).map(|(c, _)| c).collect::<~[ComponentValue]>(); let serialized = component_values.iter().to_css(); - tokenize(serialized).map(|(c, _)| c).collect::<~[ComponentValue]>() + tokenize(serialized.as_slice()).map(|(c, _)| c).collect::<~[ComponentValue]>() }); } @@ -301,10 +306,10 @@ impl ToJson for Result { impl ToJson for SyntaxError { fn to_json(&self) -> json::Json { - json::List(~[json::String(~"error"), json::String(match self.reason { - ErrEmptyInput => ~"empty", - ErrExtraInput => ~"extra-input", - _ => ~"invalid", + json::List(~[JString!("error"), JString!(match self.reason { + ErrEmptyInput => "empty", + ErrExtraInput => "extra-input", + _ => "invalid", })]) } } @@ -314,7 +319,7 @@ impl ToJson for Color { fn to_json(&self) -> json::Json { match *self { RGBA(RGBA { red: r, green: g, blue: b, alpha: a }) => (~[r, g, b, a]).to_json(), - CurrentColor => json::String(~"currentColor"), + CurrentColor => JString!("currentColor"), } } } @@ -340,7 +345,7 @@ impl ToJson for DeclarationListItem { } -fn list_to_json(list: &~[(ComponentValue, SourceLocation)]) -> ~[json::Json] { +fn list_to_json(list: &Vec<(ComponentValue, SourceLocation)>) -> ~[json::Json] { list.iter().map(|tuple| { match *tuple { (ref c, _) => c.to_json() @@ -353,7 +358,7 @@ impl ToJson for AtRule { fn to_json(&self) -> json::Json { match *self { AtRule{name: ref name, prelude: ref prelude, block: ref block, ..} - => json::List(~[json::String(~"at-rule"), name.to_json(), + => json::List(~[JString!("at-rule"), name.to_json(), prelude.to_json(), block.as_ref().map(list_to_json).to_json()]) } } @@ -364,7 +369,7 @@ impl ToJson for QualifiedRule { fn to_json(&self) -> json::Json { match *self { QualifiedRule{prelude: ref prelude, block: ref block, ..} - => json::List(~[json::String(~"qualified rule"), + => json::List(~[JString!("qualified rule"), prelude.to_json(), json::List(list_to_json(block))]) } } @@ -375,7 +380,7 @@ impl ToJson for Declaration { fn to_json(&self) -> json::Json { match *self { Declaration{name: ref name, value: ref value, important: ref important, ..} - => json::List(~[json::String(~"declaration"), name.to_json(), + => json::List(~[JString!("declaration"), name.to_json(), value.to_json(), important.to_json()]) } } @@ -385,63 +390,62 @@ impl ToJson for Declaration { impl ToJson for ComponentValue { fn to_json(&self) -> json::Json { use JList = serialize::json::List; - use JString = serialize::json::String; fn numeric(value: &NumericValue) -> ~[json::Json] { match *value { NumericValue{representation: ref r, value: ref v, int_value: ref i} => ~[r.to_json(), v.to_json(), - JString(match *i { Some(_) => ~"integer", _ => ~"number" })] + JString!(match *i { Some(_) => "integer", _ => "number" })] } } match *self { - Ident(ref value) => JList(~[JString(~"ident"), value.to_json()]), - AtKeyword(ref value) => JList(~[JString(~"at-keyword"), value.to_json()]), - Hash(ref value) => JList(~[JString(~"hash"), value.to_json(), - JString(~"unrestricted")]), - IDHash(ref value) => JList(~[JString(~"hash"), value.to_json(), JString(~"id")]), - String(ref value) => JList(~[JString(~"string"), value.to_json()]), - URL(ref value) => JList(~[JString(~"url"), value.to_json()]), - Delim('\\') => JString(~"\\"), - Delim(value) => JString(str::from_char(value)), - - Number(ref value) => JList(~[JString(~"number")] + numeric(value)), - Percentage(ref value) => JList(~[JString(~"percentage")] + numeric(value)), + Ident(ref value) => JList(~[JString!("ident"), value.to_json()]), + AtKeyword(ref value) => JList(~[JString!("at-keyword"), value.to_json()]), + Hash(ref value) => JList(~[JString!("hash"), value.to_json(), + JString!("unrestricted")]), + IDHash(ref value) => JList(~[JString!("hash"), value.to_json(), JString!("id")]), + String(ref value) => JList(~[JString!("string"), value.to_json()]), + URL(ref value) => JList(~[JString!("url"), value.to_json()]), + Delim('\\') => JString!("\\"), + Delim(value) => json::String(str::from_char(value)), + + Number(ref value) => JList(~[JString!("number")] + numeric(value)), + Percentage(ref value) => JList(~[JString!("percentage")] + numeric(value)), Dimension(ref value, ref unit) - => JList(~[JString(~"dimension")] + numeric(value) + ~[unit.to_json()]), + => JList(~[JString!("dimension")] + numeric(value) + ~[unit.to_json()]), UnicodeRange(start, end) - => JList(~[JString(~"unicode-range"), start.to_json(), end.to_json()]), - - WhiteSpace => JString(~" "), - Colon => JString(~":"), - Semicolon => JString(~";"), - Comma => JString(~","), - IncludeMatch => JString(~"~="), - DashMatch => JString(~"|="), - PrefixMatch => JString(~"^="), - SuffixMatch => JString(~"$="), - SubstringMatch => JString(~"*="), - Column => JString(~"||"), - CDO => JString(~""), + => JList(~[JString!("unicode-range"), start.to_json(), end.to_json()]), + + WhiteSpace => JString!(" "), + Colon => JString!(":"), + Semicolon => JString!(";"), + Comma => JString!(","), + IncludeMatch => JString!("~="), + DashMatch => JString!("|="), + PrefixMatch => JString!("^="), + SuffixMatch => JString!("$="), + SubstringMatch => JString!("*="), + Column => JString!("||"), + CDO => JString!(""), Function(ref name, ref arguments) - => JList(~[JString(~"function"), name.to_json()] + + => JList(~[JString!("function"), name.to_json()] + arguments.iter().map(|a| a.to_json()).collect::<~[json::Json]>()), ParenthesisBlock(ref content) - => JList(~[JString(~"()")] + content.iter().map(|c| c.to_json()).collect::<~[json::Json]>()), + => JList(~[JString!("()")] + content.iter().map(|c| c.to_json()).collect::<~[json::Json]>()), SquareBracketBlock(ref content) - => JList(~[JString(~"[]")] + content.iter().map(|c| c.to_json()).collect::<~[json::Json]>()), + => JList(~[JString!("[]")] + content.iter().map(|c| c.to_json()).collect::<~[json::Json]>()), CurlyBracketBlock(ref content) - => JList(~[JString(~"{}")] + list_to_json(content)), + => JList(~[JString!("{}")] + list_to_json(content)), - BadURL => JList(~[JString(~"error"), JString(~"bad-url")]), - BadString => JList(~[JString(~"error"), JString(~"bad-string")]), - CloseParenthesis => JList(~[JString(~"error"), JString(~")")]), - CloseSquareBracket => JList(~[JString(~"error"), JString(~"]")]), - CloseCurlyBracket => JList(~[JString(~"error"), JString(~"}")]), + BadURL => JList(~[JString!("error"), JString!("bad-url")]), + BadString => JList(~[JString!("error"), JString!("bad-string")]), + CloseParenthesis => JList(~[JString!("error"), JString!(")")]), + CloseSquareBracket => JList(~[JString!("error"), JString!("]")]), + CloseCurlyBracket => JList(~[JString!("error"), JString!("}")]), } } } diff --git a/tokenizer.rs b/tokenizer.rs index b3942980..29726282 100644 --- a/tokenizer.rs +++ b/tokenizer.rs @@ -4,7 +4,7 @@ // http://dev.w3.org/csswg/css3-syntax/#tokenization -use std::{char, str, num}; +use std::{char, num}; use std::ascii::StrAsciiExt; use ast::*; @@ -40,9 +40,9 @@ fn preprocess(input: &str) -> ~str { #[test] fn test_preprocess() { - assert!(preprocess("") == ~""); - assert!(preprocess("Lorem\r\n\t\x00ipusm\ndoror\uFFFD\r") - == ~"Lorem\n\t\uFFFDipusm\ndoror\uFFFD\n"); + assert!("" == preprocess("")); + assert!("Lorem\n\t\uFFFDipusm\ndoror\uFFFD\n" == + preprocess("Lorem\r\n\t\x00ipusm\ndoror\uFFFD\r")); } @@ -273,9 +273,9 @@ fn consume_comments(tokenizer: &mut Tokenizer) { } -fn consume_block(tokenizer: &mut Tokenizer, ending_token: ComponentValue) -> ~[ComponentValue] { +fn consume_block(tokenizer: &mut Tokenizer, ending_token: ComponentValue) -> Vec { tokenizer.position += 1; // Skip the initial {[( - let mut content = ~[]; + let mut content = Vec::new(); loop { match next_component_value(tokenizer) { Some((component_value, _location)) => { @@ -289,9 +289,9 @@ fn consume_block(tokenizer: &mut Tokenizer, ending_token: ComponentValue) -> ~[C } -fn consume_block_with_location(tokenizer: &mut Tokenizer, ending_token: ComponentValue) -> ~[Node] { +fn consume_block_with_location(tokenizer: &mut Tokenizer, ending_token: ComponentValue) -> Vec { tokenizer.position += 1; // Skip the initial {[( - let mut content = ~[]; + let mut content = Vec::new(); loop { match next_component_value(tokenizer) { Some((component_value, location)) => { @@ -314,9 +314,9 @@ fn consume_string(tokenizer: &mut Tokenizer, single_quote: bool) -> ComponentVal // Return None on syntax error (ie. unescaped newline) -fn consume_quoted_string(tokenizer: &mut Tokenizer, single_quote: bool) -> Option<~str> { +fn consume_quoted_string(tokenizer: &mut Tokenizer, single_quote: bool) -> Option { tokenizer.position += 1; // Skip the initial quote - let mut string: ~str = ~""; + let mut string = StrBuf::new(); while !tokenizer.is_eof() { match tokenizer.consume_char() { '"' if !single_quote => break, @@ -360,15 +360,15 @@ fn is_ident_start(tokenizer: &mut Tokenizer) -> bool { fn consume_ident_like(tokenizer: &mut Tokenizer) -> ComponentValue { let value = consume_name(tokenizer); if !tokenizer.is_eof() && tokenizer.current_char() == '(' { - if value.eq_ignore_ascii_case("url") { consume_url(tokenizer) } + if value.as_slice().eq_ignore_ascii_case("url") { consume_url(tokenizer) } else { Function(value, consume_block(tokenizer, CloseParenthesis)) } } else { Ident(value) } } -fn consume_name(tokenizer: &mut Tokenizer) -> ~str { - let mut value = ~""; +fn consume_name(tokenizer: &mut Tokenizer) -> StrBuf { + let mut value = StrBuf::new(); while !tokenizer.is_eof() { let c = tokenizer.current_char(); value.push_char(match c { @@ -389,7 +389,7 @@ fn consume_name(tokenizer: &mut Tokenizer) -> ~str { fn consume_numeric(tokenizer: &mut Tokenizer) -> ComponentValue { // Parse [+-]?\d*(\.\d+)?([eE][+-]?\d+)? // But this is always called so that there is at least one digit in \d*(\.\d+)? - let mut representation = ~""; + let mut representation = StrBuf::new(); let mut is_integer = true; if is_match!(tokenizer.current_char(), '-' | '+') { representation.push_char(tokenizer.consume_char()) @@ -438,13 +438,13 @@ fn consume_numeric(tokenizer: &mut Tokenizer) -> ComponentValue { let value = NumericValue { int_value: if is_integer { Some( // Remove any + sign as int::from_str() does not parse them. - if representation[0] != '+' as u8 { - from_str(representation) + if representation.as_slice().starts_with("+") { + from_str(representation.as_slice().slice_from(1)) } else { - from_str(representation.slice_from(1)) + from_str(representation.as_slice()) }.unwrap() )} else { None }, - value: from_str(representation).unwrap(), + value: from_str(representation.as_slice()).unwrap(), representation: representation, }; if !tokenizer.is_eof() && tokenizer.current_char() == '%' { @@ -471,7 +471,7 @@ fn consume_url(tokenizer: &mut Tokenizer) -> ComponentValue { _ => return consume_unquoted_url(tokenizer), } } - return URL(~""); + return URL(StrBuf::new()); fn consume_quoted_url(tokenizer: &mut Tokenizer, single_quote: bool) -> ComponentValue { match consume_quoted_string(tokenizer, single_quote) { @@ -481,7 +481,7 @@ fn consume_url(tokenizer: &mut Tokenizer) -> ComponentValue { } fn consume_unquoted_url(tokenizer: &mut Tokenizer) -> ComponentValue { - let mut string = ~""; + let mut string = StrBuf::new(); while !tokenizer.is_eof() { let next_char = match tokenizer.consume_char() { ' ' | '\t' => return consume_url_end(tokenizer, string), @@ -505,7 +505,7 @@ fn consume_url(tokenizer: &mut Tokenizer) -> ComponentValue { URL(string) } - fn consume_url_end(tokenizer: &mut Tokenizer, string: ~str) -> ComponentValue { + fn consume_url_end(tokenizer: &mut Tokenizer, string: StrBuf) -> ComponentValue { while !tokenizer.is_eof() { match tokenizer.consume_char() { ' ' | '\t' => (), @@ -535,7 +535,7 @@ fn consume_url(tokenizer: &mut Tokenizer) -> ComponentValue { fn consume_unicode_range(tokenizer: &mut Tokenizer) -> ComponentValue { tokenizer.position += 2; // Skip U+ - let mut hex = ~""; + let mut hex = StrBuf::new(); while hex.len() < 6 && !tokenizer.is_eof() && is_match!(tokenizer.current_char(), '0'..'9' | 'A'..'F' | 'a'..'f') { hex.push_char(tokenizer.consume_char()); @@ -550,11 +550,11 @@ fn consume_unicode_range(tokenizer: &mut Tokenizer) -> ComponentValue { let start; let end; if question_marks > 0 { - start = num::from_str_radix(hex + "0".repeat(question_marks), 16).unwrap(); - end = num::from_str_radix(hex + "F".repeat(question_marks), 16).unwrap(); + start = num::from_str_radix(hex.clone().append("0".repeat(question_marks)).as_slice(), 16).unwrap(); + end = num::from_str_radix(hex.append("F".repeat(question_marks)).as_slice(), 16).unwrap(); } else { - start = num::from_str_radix(hex, 16).unwrap(); - hex = ~""; + start = num::from_str_radix(hex.as_slice(), 16).unwrap(); + hex.truncate(0); if !tokenizer.is_eof() && tokenizer.current_char() == '-' { tokenizer.position += 1; while hex.len() < 6 && !tokenizer.is_eof() { @@ -566,7 +566,7 @@ fn consume_unicode_range(tokenizer: &mut Tokenizer) -> ComponentValue { } } } - end = if hex.len() > 0 { num::from_str_radix(hex, 16).unwrap() } else { start } + end = if hex.len() > 0 { num::from_str_radix(hex.as_slice(), 16).unwrap() } else { start } } UnicodeRange(start, end) } @@ -580,7 +580,7 @@ fn consume_escape(tokenizer: &mut Tokenizer) -> char { let c = tokenizer.consume_char(); match c { '0'..'9' | 'A'..'F' | 'a'..'f' => { - let mut hex = str::from_char(c); + let mut hex = StrBuf::from_char(1, c); while hex.len() < 6 && !tokenizer.is_eof() { let c = tokenizer.current_char(); match c { @@ -597,7 +597,7 @@ fn consume_escape(tokenizer: &mut Tokenizer) -> char { } } static REPLACEMENT_CHAR: char = '\uFFFD'; - let c: u32 = num::from_str_radix(hex, 16).unwrap(); + let c: u32 = num::from_str_radix(hex.as_slice(), 16).unwrap(); if c != 0 { let c = char::from_u32(c); c.unwrap_or(REPLACEMENT_CHAR)