Skip to content

Commit 70e4769

Browse files
committed
Cleanup.
Raw f64 in some more places, use rust std f64 parsing for numbers.
1 parent 76b6638 commit 70e4769

File tree

6 files changed

+34
-90
lines changed

6 files changed

+34
-90
lines changed

rsass/src/parser/value.rs

+17-69
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ use super::{
1010
input_to_string, list_or_single, position, sass_string, PResult, Span,
1111
};
1212
use crate::sass::{BinOp, SassString, Value};
13-
use crate::value::{ListSeparator, Number, Numeric, Operator, Rgba};
13+
use crate::value::{ListSeparator, Numeric, Operator, Rgba};
1414
use nom::branch::alt;
1515
use nom::bytes::complete::{tag, tag_no_case};
1616
use nom::character::complete::{
1717
alphanumeric1, char, digit1, multispace0, multispace1, one_of,
1818
};
1919
use nom::combinator::{
20-
cut, into, map, map_res, not, opt, peek, recognize, success, value,
20+
cut, into, map, map_opt, map_res, not, opt, peek, recognize, value,
2121
verify,
2222
};
2323
use nom::error::context;
24-
use nom::multi::{fold_many0, fold_many1, many0, many_m_n, separated_list1};
24+
use nom::multi::{fold_many0, many0, many_m_n, separated_list1};
2525
use nom::sequence::{delimited, pair, preceded, terminated, tuple};
2626
use std::str::from_utf8;
2727

@@ -332,68 +332,20 @@ pub fn numeric(input: Span) -> PResult<Numeric> {
332332
})(input)
333333
}
334334

335-
pub fn number(input: Span) -> PResult<Number> {
336-
map(
337-
tuple((
338-
sign_neg,
335+
pub fn number(input: Span) -> PResult<f64> {
336+
map_opt(
337+
recognize(delimited(
338+
opt(one_of("+-")),
339339
alt((
340-
map(pair(decimal_integer, decimal_decimals), |(n, d)| n + d),
341-
decimal_decimals,
342-
decimal_integer,
343-
)),
344-
opt(preceded(
345-
alt((tag("e"), tag("E"))),
346-
tuple((sign_neg, decimal_i32)),
340+
terminated(digit1, opt(terminated(char('.'), digit1))),
341+
preceded(char('.'), digit1),
347342
)),
343+
opt(delimited(one_of("eE"), opt(one_of("+-")), digit1)),
348344
)),
349-
|(is_neg, num, exp)| {
350-
let value = if is_neg { -num } else { num };
351-
Number::from(if let Some((e_neg, e_val)) = exp {
352-
let e_val = if e_neg { -e_val } else { e_val };
353-
// Note: powi sounds right, but looses some precision.
354-
value * 10f64.powf(e_val.into())
355-
} else {
356-
value
357-
})
358-
},
359-
)(input)
360-
}
361-
362-
/// Parse true on `-` and false on `+` or no sign.
363-
fn sign_neg(input: Span) -> PResult<bool> {
364-
alt((
365-
value(true, char('-')),
366-
value(false, char('+')),
367-
success(false),
368-
))(input)
369-
}
370-
371-
pub fn decimal_integer(input: Span) -> PResult<f64> {
372-
map(digit1, |s: Span| {
373-
s.fragment()
374-
.iter()
375-
.fold(0.0, |r, d| (r * 10.) + f64::from(d - b'0'))
376-
})(input)
377-
}
378-
pub fn decimal_i32(input: Span) -> PResult<i32> {
379-
fold_many1(
380-
// Note: We should use bytes directly, one_of returns a char.
381-
one_of("0123456789"),
382-
|| 0,
383-
|r, d| (r * 10) + i32::from(d as u8 - b'0'),
345+
|s: Span| from_utf8(s.fragment()).ok()?.parse().ok(),
384346
)(input)
385347
}
386348

387-
pub fn decimal_decimals(input: Span) -> PResult<f64> {
388-
map(preceded(char('.'), digit1), |s: Span| {
389-
let digits = s.fragment();
390-
digits
391-
.iter()
392-
.fold(0.0, |r, d| (r * 10.) + f64::from(d - b'0'))
393-
* (10f64).powf(-(digits.len() as f64))
394-
})(input)
395-
}
396-
397349
pub fn variable_nomod(input: Span) -> PResult<Value> {
398350
let (rest, name) = preceded(char('$'), identifier)(input)?;
399351
let pos = input.up_to(&rest).to_owned();
@@ -584,12 +536,12 @@ mod test {
584536

585537
#[test]
586538
fn simple_number() {
587-
check_expr("4;", number(4.))
539+
check_expr("4;", Value::scalar(4.))
588540
}
589541

590542
#[test]
591543
fn simple_number_neg() {
592-
check_expr("-4;", number(-4.))
544+
check_expr("-4;", Value::scalar(-4.))
593545
}
594546

595547
#[test]
@@ -599,23 +551,19 @@ mod test {
599551

600552
#[test]
601553
fn simple_number_dec() {
602-
check_expr("4.34;", number(4.34))
554+
check_expr("4.34;", Value::scalar(4.34))
603555
}
604556
#[test]
605557
fn simple_number_onlydec() {
606-
check_expr(".34;", number(0.34))
558+
check_expr(".34;", Value::scalar(0.34))
607559
}
608560
#[test]
609561
fn simple_number_onlydec_neg() {
610-
check_expr("-.34;", number(-0.34))
562+
check_expr("-.34;", Value::scalar(-0.34))
611563
}
612564
#[test]
613565
fn simple_number_onlydec_pos() {
614-
check_expr("+.34;", number(0.34))
615-
}
616-
617-
fn number(value: f64) -> Value {
618-
Value::scalar(value)
566+
check_expr("+.34;", Value::scalar(0.34))
619567
}
620568

621569
#[test]

rsass/src/value/numeric.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl Numeric {
5555
pub fn as_unit(&self, unit: Unit) -> Option<Number> {
5656
self.unit
5757
.scale_to_unit(&unit)
58-
.map(|scale| &self.value * &scale)
58+
.map(|scale| &self.value * &Number::from(scale))
5959
}
6060
/// Convert this numeric value to a given unit, if possible.
6161
///
@@ -67,7 +67,9 @@ impl Numeric {
6767
/// assert_eq!(inch.as_unit(Unit::Deg), None);
6868
/// ```
6969
pub fn as_unitset(&self, unit: &UnitSet) -> Option<Number> {
70-
self.unit.scale_to(unit).map(|scale| &self.value * &scale)
70+
self.unit
71+
.scale_to(unit)
72+
.map(|scale| &self.value * &Number::from(scale))
7173
}
7274

7375
/// Convert this numeric value to a given unit, if possible.

rsass/src/value/unit.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! The Unit enum defines css units
22
3-
use crate::value::Number;
43
use std::f64::consts::FRAC_1_PI;
54
use std::fmt;
65

@@ -150,9 +149,9 @@ impl Unit {
150149
/// Get a scaling factor to convert this unit to another unit.
151150
///
152151
/// Returns None if the units are of different dimension.
153-
pub fn scale_to(&self, other: &Self) -> Option<Number> {
152+
pub fn scale_to(&self, other: &Self) -> Option<f64> {
154153
if self == other {
155-
Some(1.into())
154+
Some(1.)
156155
} else if self.dimension() == other.dimension() {
157156
Some(self.scale_factor() / other.scale_factor())
158157
} else {
@@ -163,9 +162,9 @@ impl Unit {
163162
/// Some of these are exact and correct, others are more arbitrary.
164163
/// When comparing 10cm to 4in, these factors will give correct results.
165164
/// When comparing rems to vw, who can say?
166-
pub(crate) fn scale_factor(&self) -> Number {
165+
pub(crate) fn scale_factor(&self) -> f64 {
167166
#[allow(clippy::match_same_arms)]
168-
Number::from(match *self {
167+
match *self {
169168
Self::Em | Self::Rem => 10. / 2.,
170169
Self::Ex => 10. / 3.,
171170
Self::Ch => 10. / 4.,
@@ -198,7 +197,7 @@ impl Unit {
198197
Self::None => 1.,
199198

200199
Self::Unknown(_) => 1.,
201-
})
200+
}
202201
}
203202
}
204203

rsass/src/value/unitset.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,15 @@ impl UnitSet {
8383
/// Get a scaling factor to convert this unit to another unit.
8484
///
8585
/// Returns None if the units are of different dimension.
86-
pub fn scale_to(&self, other: &Self) -> Option<Number> {
86+
pub fn scale_to(&self, other: &Self) -> Option<f64> {
8787
if let [(u, 1)] = other.units.as_slice() {
8888
self.scale_to_unit(u)
8989
} else if other.is_none() {
9090
self.scale_to_unit(&Unit::None)
9191
} else {
9292
let quote = self / other;
9393
if quote.dimension().is_empty() {
94-
Some(quote.units.iter().fold(1.into(), |a, (unit, power)| {
94+
Some(quote.units.iter().fold(1., |a, (unit, power)| {
9595
a * unit.scale_factor().powi((*power).into())
9696
}))
9797
} else {
@@ -103,7 +103,7 @@ impl UnitSet {
103103
/// Get a scaling factor to convert this unit to another unit.
104104
///
105105
/// Returns None if the units are of different dimension.
106-
pub fn scale_to_unit(&self, other: &Unit) -> Option<Number> {
106+
pub fn scale_to_unit(&self, other: &Unit) -> Option<f64> {
107107
if let [(u, 1)] = self.units.as_slice() {
108108
u.scale_to(other)
109109
} else if self.is_none() {
@@ -116,19 +116,19 @@ impl UnitSet {
116116

117117
/// Simplify this unit set, returning a scaling factor.
118118
pub fn simplify(&mut self) -> Number {
119-
let mut factor = 1.into();
119+
let mut factor = 1.;
120120
if self.units.len() > 1 {
121121
for i in 1..(self.units.len()) {
122122
let (a, b) = self.units.split_at_mut(i);
123123
let (au, ap) = a.last_mut().unwrap();
124124
for (bu, bp) in b {
125125
if let Some(f) = bu.scale_to(au) {
126126
if ap.abs() > bp.abs() {
127-
factor = factor * f.powi((*bp).into());
127+
factor *= f.powi((*bp).into());
128128
*ap += *bp;
129129
*bp = 0;
130130
} else {
131-
factor = factor / f.powi((*ap).into());
131+
factor /= f.powi((*ap).into());
132132
*bp += *ap;
133133
*ap = 0;
134134
}
@@ -137,7 +137,7 @@ impl UnitSet {
137137
}
138138
}
139139
self.units.retain(|(_u, p)| *p != 0);
140-
factor
140+
factor.into()
141141
}
142142
}
143143

rsass/tests/misc/fuzz_cases.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ fn decimal_integer_overflow() {
1515
assert_eq!(
1616
compile_value(b"2000000000000000000000000000000000000", FORMAT)
1717
.unwrap(),
18-
b"1999999999999999800000000000000000000".to_vec(),
18+
b"2000000000000000000000000000000000000".to_vec(),
1919
);
2020
}
2121

rsass/tests/spec/values/numbers/bounds.rs

-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ mod int {
1414
use super::runner;
1515

1616
#[test]
17-
#[ignore] // wrong result
1817
fn slightly() {
1918
assert_eq!(
2019
runner().ok(
@@ -44,7 +43,6 @@ mod int {
4443
use super::runner;
4544

4645
#[test]
47-
#[ignore] // wrong result
4846
fn slightly() {
4947
assert_eq!(
5048
runner().ok(
@@ -70,7 +68,6 @@ mod int {
7068
}
7169
}
7270
#[test]
73-
#[ignore] // wrong result
7471
fn max_value() {
7572
assert_eq!(
7673
runner().ok(
@@ -82,7 +79,6 @@ mod int {
8279
);
8380
}
8481
#[test]
85-
#[ignore] // wrong result
8682
fn min_value() {
8783
assert_eq!(
8884
runner().ok(
@@ -194,7 +190,6 @@ mod precision_limit {
194190
use super::runner;
195191

196192
#[test]
197-
#[ignore] // wrong result
198193
fn after_decimal() {
199194
assert_eq!(
200195
runner().ok(

0 commit comments

Comments
 (0)