Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Inline fields of Token::Number to align with Token::Dimension
  • Loading branch information
SimonSapin committed Jun 16, 2017
commit 2733bb305e3f8664b625b4bf4fae0388d00643cb
9 changes: 4 additions & 5 deletions src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use std::fmt;
use std::f32::consts::PI;

use super::{Token, Parser, ToCss, ParseError, BasicParseError};
use tokenizer::NumericValue;

#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
Expand Down Expand Up @@ -430,7 +429,7 @@ fn parse_color_function<'i, 't>(name: &str, arguments: &mut Parser<'i, 't>) -> R
};
let token = try!(arguments.next());
match token {
Token::Number(NumericValue { value: v, .. }) => {
Token::Number { value: v, .. } => {
clamp_unit_f32(v)
}
Token::Percentage(ref v) => {
Expand Down Expand Up @@ -459,10 +458,10 @@ fn parse_rgb_components_rgb<'i, 't>(arguments: &mut Parser<'i, 't>) -> Result<(u
// Either integers or percentages, but all the same type.
// https://drafts.csswg.org/css-color/#rgb-functions
match try!(arguments.next()) {
Token::Number(NumericValue { value: v, .. }) => {
Token::Number { value: v, .. } => {
red = clamp_floor_256_f32(v);
green = clamp_floor_256_f32(match try!(arguments.next()) {
Token::Number(NumericValue { value: v, .. }) => v,
Token::Number { value: v, .. } => v,
Token::Comma => {
uses_commas = true;
try!(arguments.expect_number())
Expand Down Expand Up @@ -501,7 +500,7 @@ fn parse_rgb_components_hsl<'i, 't>(arguments: &mut Parser<'i, 't>) -> Result<(u
// 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::Number { value: v, .. } => Ok(v),
Token::Dimension { value: v, ref unit, .. } => {
match_ignore_ascii_case! { &*unit,
"deg" => Ok(v),
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ fn parse_border_spacing(_context: &ParserContext, input: &mut Parser)

pub use cssparser_macros::*;

pub use tokenizer::{Token, NumericValue, PercentageValue, SourceLocation};
pub use tokenizer::{Token, PercentageValue, SourceLocation};
pub use rules_and_declarations::{parse_important};
pub use rules_and_declarations::{DeclarationParser, DeclarationListParser, parse_one_declaration};
pub use rules_and_declarations::{RuleListParser, parse_one_rule};
Expand Down
21 changes: 4 additions & 17 deletions src/nth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,8 @@ use super::{Token, Parser, BasicParseError};
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(()),
}
Token::Number { int_value: Some(b), .. } => {
Ok((0, b))
}
Token::Dimension { int_value: Some(a), ref unit, .. } => {
match_ignore_ascii_case! {
Expand Down Expand Up @@ -66,12 +63,7 @@ fn parse_b<'i, 't>(input: &mut Parser<'i, 't>, a: i32) -> Result<(i32, i32), Bas
match token {
Ok(Token::Delim('+')) => Ok(try!(parse_signless_b(input, a, 1))),
Ok(Token::Delim('-')) => Ok(try!(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(Token::Number { has_sign: true, int_value: Some(b), .. }) => Ok((a, b)),
_ => {
input.reset(start_position);
Ok((a, 0))
Expand All @@ -82,12 +74,7 @@ fn parse_b<'i, 't>(input: &mut Parser<'i, 't>, a: i32) -> Result<(i32, i32), Bas
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 {
Token::Number(ref value) if !value.has_sign => {
match value.int_value {
Some(v) => Ok((a, b_sign * v as i32)),
None => Err(()),
}
}
Token::Number { has_sign: false, int_value: Some(b), .. } => Ok((a, b_sign * b)),
_ => Err(())
}.map_err(|()| BasicParseError::UnexpectedToken(token))
}
Expand Down
6 changes: 3 additions & 3 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use compact_cow_str::CompactCowStr;
use std::ops::Range;
use std::ascii::AsciiExt;
use std::ops::BitOr;
use tokenizer::{self, Token, NumericValue, PercentageValue, Tokenizer, SourceLocation};
use tokenizer::{self, Token, PercentageValue, Tokenizer, SourceLocation};


/// A capture of the internal state of a `Parser` (including the position within the input),
Expand Down Expand Up @@ -507,7 +507,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
#[inline]
pub fn expect_number(&mut self) -> Result<f32, BasicParseError<'i>> {
match try!(self.next()) {
Token::Number(NumericValue { value, .. }) => Ok(value),
Token::Number { value, .. } => Ok(value),
t => Err(BasicParseError::UnexpectedToken(t))
}
}
Expand All @@ -517,7 +517,7 @@ impl<'i: 't, 't> Parser<'i, 't> {
pub fn expect_integer(&mut self) -> Result<i32, BasicParseError<'i>> {
let token = try!(self.next());
match token {
Token::Number(NumericValue { int_value: Some(int_value), .. }) => {
Token::Number { int_value: Some(int_value), .. } => {
Ok(int_value)
}
t => Err(BasicParseError::UnexpectedToken(t))
Expand Down
32 changes: 13 additions & 19 deletions src/serializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use std::ascii::AsciiExt;
use std::fmt::{self, Write};

use super::{Token, NumericValue, PercentageValue};
use super::{Token, PercentageValue};


/// Trait for things the can serialize themselves in CSS syntax.
Expand Down Expand Up @@ -43,20 +43,21 @@ pub trait ToCss {


#[inline]
fn write_numeric<W>(value: NumericValue, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn write_numeric<W>(value: f32, int_value: Option<i32>, has_sign: bool, dest: &mut W)
-> fmt::Result where W: fmt::Write {
// `value.value >= 0` is true for negative 0.
if value.has_sign && value.value.is_sign_positive() {
if has_sign && value.is_sign_positive() {
try!(dest.write_str("+"));
}

if value.value == 0.0 && value.value.is_sign_negative() {
if value == 0.0 && value.is_sign_negative() {
// Negative zero. Work around #20596.
try!(dest.write_str("-0"))
} else {
try!(write!(dest, "{}", value.value))
try!(write!(dest, "{}", value))
}

if value.int_value.is_none() && value.value.fract() == 0. {
if int_value.is_none() && value.fract() == 0. {
try!(dest.write_str(".0"));
}
Ok(())
Expand Down Expand Up @@ -87,22 +88,15 @@ impl<'a> ToCss for Token<'a> {
},
Token::Delim(value) => try!(write!(dest, "{}", value)),

Token::Number(value) => try!(write_numeric(value, dest)),
Token::Number { value, int_value, has_sign } => {
try!(write_numeric(value, int_value, has_sign, dest))
}
Token::Percentage(PercentageValue { unit_value, int_value, has_sign }) => {
let value = NumericValue {
value: unit_value * 100.,
int_value: int_value,
has_sign: has_sign,
};
try!(write_numeric(value, dest));
try!(write_numeric(unit_value * 100., int_value, has_sign, dest));
try!(dest.write_str("%"));
},
Token::Dimension { value, int_value, has_sign, ref unit } => {
try!(write_numeric(NumericValue {
value: value,
int_value: int_value,
has_sign: has_sign,
}, dest));
try!(write_numeric(value, int_value, has_sign, dest));
// Disambiguate with scientific notation.
let unit = &**unit;
if unit == "e" || unit == "E" || unit.starts_with("e-") || unit.starts_with("E-") {
Expand Down Expand Up @@ -393,7 +387,7 @@ impl<'a> Token<'a> {
Token::Delim('|') => DelimBar,
Token::Delim('/') => DelimSlash,
Token::Delim('*') => DelimAsterisk,
Token::Number(_) => Number,
Token::Number { .. } => Number,
Token::Percentage(_) => Percentage,
Token::Dimension { .. } => Dimension,
Token::WhiteSpace(_) => WhiteSpace,
Expand Down
3 changes: 1 addition & 2 deletions src/size_of_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use compact_cow_str::CompactCowStr;
use std::borrow::Cow;
use tokenizer::{Token, NumericValue, PercentageValue};
use tokenizer::{Token, PercentageValue};

#[macro_export]
macro_rules! size_of_test {
Expand Down Expand Up @@ -33,7 +33,6 @@ macro_rules! size_of_test {

// These assume 64-bit
size_of_test!(token, Token, 32);
size_of_test!(numeric_value, NumericValue, 16);
size_of_test!(percentage_value, PercentageValue, 16);
size_of_test!(std_cow_str, Cow<'static, str>, 32);
size_of_test!(compact_cow_str, CompactCowStr, 16);
30 changes: 13 additions & 17 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rustc_serialize::json::{self, Json, ToJson};
#[cfg(feature = "bench")]
use self::test::Bencher;

use super::{Parser, Delimiter, Token, NumericValue, PercentageValue, SourceLocation, ParseError,
use super::{Parser, Delimiter, Token, PercentageValue, SourceLocation, ParseError,
DeclarationListParser, DeclarationParser, RuleListParser, BasicParseError,
AtRuleType, AtRuleParser, QualifiedRuleParser, ParserInput,
parse_one_declaration, parse_one_rule, parse_important,
Expand Down Expand Up @@ -768,11 +768,15 @@ fn component_values_to_json(input: &mut Parser) -> Vec<Json> {
}

fn one_component_value_to_json(token: Token, input: &mut Parser) -> Json {
fn numeric(value: NumericValue) -> Vec<json::Json> {
fn numeric(value: f32, int_value: Option<i32>, has_sign: bool) -> Vec<json::Json> {
vec![
Token::Number(value).to_css_string().to_json(),
match value.int_value { Some(i) => i.to_json(), None => value.value.to_json() },
match value.int_value { Some(_) => "integer", None => "number" }.to_json()
Token::Number {
value: value,
int_value: int_value,
has_sign: has_sign,
}.to_css_string().to_json(),
match int_value { Some(i) => i.to_json(), None => value.to_json() },
match int_value { Some(_) => "integer", None => "number" }.to_json()
]
}

Expand All @@ -793,27 +797,19 @@ fn one_component_value_to_json(token: Token, input: &mut Parser) -> Json {
Token::Delim('\\') => "\\".to_json(),
Token::Delim(value) => value.to_string().to_json(),

Token::Number(value) => Json::Array({
Token::Number { value, int_value, has_sign } => Json::Array({
let mut v = vec!["number".to_json()];
v.extend(numeric(value));
v.extend(numeric(value, int_value, has_sign));
v
}),
Token::Percentage(PercentageValue { unit_value, int_value, has_sign }) => Json::Array({
let mut v = vec!["percentage".to_json()];
v.extend(numeric(NumericValue {
value: unit_value * 100.,
int_value: int_value,
has_sign: has_sign,
}));
v.extend(numeric(unit_value * 100., int_value, has_sign));
v
}),
Token::Dimension { value, int_value, has_sign, unit } => Json::Array({
let mut v = vec!["dimension".to_json()];
v.extend(numeric(NumericValue {
value: value,
int_value: int_value,
has_sign: has_sign,
}));
v.extend(numeric(value, int_value, has_sign));
v.push(unit.to_json());
v
}),
Expand Down
33 changes: 14 additions & 19 deletions src/tokenizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,18 @@ pub enum Token<'a> {
Delim(char),

/// A [`<number-token>`](https://drafts.csswg.org/css-syntax/#number-token-diagram)
Number(NumericValue),
Number {
/// Whether the number had a `+` or `-` sign.
///
/// This is used is some cases like the <An+B> micro syntax. (See the `parse_nth` function.)
has_sign: bool,

/// The value as a float
value: f32,

/// If the origin source did not include a fractional part, the value as an integer.
int_value: Option<i32>,
},

/// A [`<percentage-token>`](https://drafts.csswg.org/css-syntax/#percentage-token-diagram)
Percentage(PercentageValue),
Expand Down Expand Up @@ -179,22 +190,6 @@ impl<'a> Token<'a> {
}


/// The numeric value of `Number` and `Dimension` tokens.
#[derive(PartialEq, Debug, Copy, Clone)]
pub struct NumericValue {
/// The value as a float
pub value: f32,

/// If the origin source did not include a fractional part, the value as an integer.
pub int_value: Option<i32>,

/// Whether the number had a `+` or `-` sign.
///
/// This is used is some cases like the <An+B> micro syntax. (See the `parse_nth` function.)
pub has_sign: bool,
}


/// The numeric value of `Percentage` tokens.
#[derive(PartialEq, Debug, Copy, Clone)]
pub struct PercentageValue {
Expand Down Expand Up @@ -893,11 +888,11 @@ fn consume_numeric<'a>(tokenizer: &mut Tokenizer<'a>) -> Token<'a> {
unit: unit,
}
} else {
Number(NumericValue {
Number {
value: value,
int_value: int_value,
has_sign: has_sign,
})
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/unicode_range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ fn parse_tokens<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(), BasicParseErro
Token::Dimension { .. } => {
parse_question_marks(input)
}
Token::Number(_) => {
Token::Number { .. } => {
let after_number = input.position();
match input.next_including_whitespace() {
Ok(Token::Delim('?')) => parse_question_marks(input),
Ok(Token::Dimension { .. }) => {}
Ok(Token::Number(_)) => {}
Ok(Token::Number { .. }) => {}
_ => input.reset(after_number)
}
}
Expand Down