Skip to content

Commit e8492fd

Browse files
authored
Use f64 for all numbers (#203)
Use f64 for all numbers instead of switching between isize rational, bignum rational and f64. The dependencies for the rationals and bignum are also removed, which should be nice for the build times.
2 parents 0a625cb + 58b5cf0 commit e8492fd

File tree

12 files changed

+201
-948
lines changed

12 files changed

+201
-948
lines changed

rsass/Cargo.toml

-4
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ arc-swap = "1.5.0"
1717
fastrand = "2.0"
1818
lazy_static = "1.0"
1919
nom = "7.0"
20-
num-bigint = { version = "0.4.0", default-features = false, features = ["std"] }
21-
num-integer = "0.1.42"
22-
num-rational = { version = "0.4.0", default-features = false, features = ["num-bigint"] }
23-
num-traits = "^0.2.0"
2420
tracing = "0.1.34"
2521

2622
[badges]

rsass/src/css/value.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::sass::Function;
66
use crate::value::{Color, ListSeparator, Number, Numeric, Operator};
77

88
/// A css value.
9-
#[derive(Clone, Debug, Eq, PartialOrd)]
9+
#[derive(Clone, Debug, PartialOrd)]
1010
pub enum Value {
1111
/// A special kind of escape. Only really used for !important.
1212
Bang(String),
@@ -311,6 +311,7 @@ impl PartialEq for Value {
311311
}
312312
}
313313
}
314+
impl Eq for Value {}
314315

315316
impl From<bool> for Value {
316317
fn from(v: bool) -> Self {

rsass/src/parser/value.rs

+20-88
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ 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::{
17-
alphanumeric1, char, multispace0, multispace1, one_of,
17+
alphanumeric1, char, digit1, multispace0, multispace1, one_of,
1818
};
1919
use nom::combinator::{
20-
cut, into, map, map_res, not, opt, peek, recognize, value, verify,
20+
cut, into, map, map_opt, map_res, not, opt, peek, recognize, value,
21+
verify,
2122
};
2223
use nom::error::context;
23-
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};
2425
use nom::sequence::{delimited, pair, preceded, terminated, tuple};
25-
use num_traits::Zero;
2626
use std::str::from_utf8;
2727

2828
pub fn value_expression(input: Span) -> PResult<Value> {
@@ -326,86 +326,23 @@ pub fn bracket_list(input: Span) -> PResult<Value> {
326326
))
327327
}
328328

329-
fn sign_prefix(input: Span) -> PResult<Option<&[u8]>> {
330-
opt(alt((tag("-"), tag("+"))))(input)
331-
.map(|(r, s)| (r, s.map(|s| s.fragment())))
332-
}
333-
334329
pub fn numeric(input: Span) -> PResult<Numeric> {
335330
map(pair(number, unit), |(number, unit)| {
336331
Numeric::new(number, unit)
337332
})(input)
338333
}
339334

340-
pub fn number(input: Span) -> PResult<Number> {
341-
map(
342-
tuple((
343-
sign_prefix,
335+
pub fn number(input: Span) -> PResult<f64> {
336+
map_opt(
337+
recognize(delimited(
338+
opt(one_of("+-")),
344339
alt((
345-
map(pair(decimal_integer, decimal_decimals), |(n, d)| n + d),
346-
decimal_decimals,
347-
decimal_integer,
348-
)),
349-
opt(preceded(
350-
alt((tag("e"), tag("E"))),
351-
tuple((sign_prefix, decimal_i32)),
340+
terminated(digit1, opt(terminated(char('.'), digit1))),
341+
preceded(char('.'), digit1),
352342
)),
343+
opt(delimited(one_of("eE"), opt(one_of("+-")), digit1)),
353344
)),
354-
|(sign, num, exp)| {
355-
let value = if sign == Some(b"-") {
356-
// Only f64-based Number can represent negative zero.
357-
if num.is_zero() {
358-
(-0.0).into()
359-
} else {
360-
-num
361-
}
362-
} else {
363-
num
364-
};
365-
if let Some((e_sign, e_val)) = exp {
366-
let e_val = if e_sign == Some(b"-") { -e_val } else { e_val };
367-
// Note: powi sounds right, but looses some precision.
368-
value * Number::from(10f64.powf(e_val.into()))
369-
} else {
370-
value
371-
}
372-
},
373-
)(input)
374-
}
375-
376-
pub fn decimal_integer(input: Span) -> PResult<Number> {
377-
fold_many1(
378-
// Note: We should use bytes directly, one_of returns a char.
379-
one_of("0123456789"),
380-
|| Number::from(0),
381-
|r, d| (r * 10) + Number::from(i64::from(d as u8 - b'0')),
382-
)(input)
383-
}
384-
pub fn decimal_i32(input: Span) -> PResult<i32> {
385-
fold_many1(
386-
// Note: We should use bytes directly, one_of returns a char.
387-
one_of("0123456789"),
388-
|| 0,
389-
|r, d| (r * 10) + i32::from(d as u8 - b'0'),
390-
)(input)
391-
}
392-
393-
pub fn decimal_decimals(input: Span) -> PResult<Number> {
394-
map(
395-
preceded(
396-
tag("."),
397-
fold_many1(
398-
one_of("0123456789"),
399-
|| (Number::from(0), Number::from(1)),
400-
|(r, n), d| {
401-
(
402-
(r * 10) + Number::from(i64::from(d as u8 - b'0')),
403-
n * 10,
404-
)
405-
},
406-
),
407-
),
408-
|(r, d)| r / d,
345+
|s: Span| from_utf8(s.fragment()).ok()?.parse().ok(),
409346
)(input)
410347
}
411348

@@ -595,43 +532,38 @@ mod test {
595532
use super::*;
596533
use crate::sass::CallArgs;
597534
use crate::sass::Value::{Color, List, Literal, Map, Paren};
598-
use crate::value::Rational;
599535
use crate::ScopeRef;
600536

601537
#[test]
602538
fn simple_number() {
603-
check_expr("4;", number(4, 1))
539+
check_expr("4;", Value::scalar(4.))
604540
}
605541

606542
#[test]
607543
fn simple_number_neg() {
608-
check_expr("-4;", number(-4, 1))
544+
check_expr("-4;", Value::scalar(-4.))
609545
}
610546

611547
#[test]
612548
fn simple_number_pos() {
613-
check_expr("+4;", Value::scalar(4))
549+
check_expr("+4;", Value::scalar(4.))
614550
}
615551

616552
#[test]
617553
fn simple_number_dec() {
618-
check_expr("4.34;", number(434, 100))
554+
check_expr("4.34;", Value::scalar(4.34))
619555
}
620556
#[test]
621557
fn simple_number_onlydec() {
622-
check_expr(".34;", number(34, 100))
558+
check_expr(".34;", Value::scalar(0.34))
623559
}
624560
#[test]
625561
fn simple_number_onlydec_neg() {
626-
check_expr("-.34;", number(-34, 100))
562+
check_expr("-.34;", Value::scalar(-0.34))
627563
}
628564
#[test]
629565
fn simple_number_onlydec_pos() {
630-
check_expr("+.34;", number(34, 100))
631-
}
632-
633-
fn number(nom: i64, denom: i64) -> Value {
634-
Value::scalar(Rational::new(nom, denom))
566+
check_expr("+.34;", Value::scalar(0.34))
635567
}
636568

637569
#[test]

rsass/src/sass/functions/color/mod.rs

+9-10
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use crate::output::Format;
88
use crate::sass::{FormalArgs, Name};
99
use crate::value::{ListSeparator, Numeric, Quotes, Unit};
1010
use crate::Scope;
11-
use num_traits::{one, zero};
1211
mod channels;
1312
mod hsl;
1413
mod hwb;
@@ -63,7 +62,7 @@ pub fn expose(m: &Scope, global: &mut FunctionMap) {
6362
/// Special perk: Defaults to 1.0 if the value is null.
6463
fn check_alpha(v: Value) -> Result<f64, String> {
6564
Ok(match v {
66-
Value::Null => one(),
65+
Value::Null => 1.0,
6766
v => {
6867
let num = Numeric::try_from(v)?;
6968
num.as_unit(Unit::None)
@@ -77,15 +76,15 @@ fn check_alpha(v: Value) -> Result<f64, String> {
7776
/// Get a rational number in the 0..1 range.
7877
fn check_alpha_range(v: Value) -> Result<f64, String> {
7978
let v = Numeric::try_from(v)?;
80-
if v.value < zero() || v.value > one() {
79+
if v.value < 0.into() || v.value > 1.into() {
8180
Err(expected_to(v, "be within 0 and 1"))
8281
} else {
8382
Ok(v.value.into())
8483
}
8584
}
8685
fn check_alpha_pm(v: Value) -> Result<f64, String> {
8786
let v = Numeric::try_from(v)?;
88-
if v.value.abs() > one() {
87+
if v.value.abs() > 1.into() {
8988
Err(expected_to(v, "be within -1 and 1"))
9089
} else {
9190
Ok(v.value.into())
@@ -140,7 +139,7 @@ fn check_expl_pct(v: Value) -> Result<f64, String> {
140139
if !val.unit.is_percent() {
141140
return Err(expected_to(val, "have unit \"%\""));
142141
}
143-
if val.value < zero() || val.value > 100.into() {
142+
if val.value < 0.into() || val.value > 100.into() {
144143
Err(expected_to(val, "be within 0% and 100%"))
145144
} else {
146145
Ok(f64::from(val.value) / 100.)
@@ -149,7 +148,7 @@ fn check_expl_pct(v: Value) -> Result<f64, String> {
149148

150149
fn check_pct_range(v: Value) -> Result<f64, String> {
151150
let val = check_pct(v)?;
152-
if val < zero() || val > one() {
151+
if val < 0.into() || val > 1.into() {
153152
Err(expected_to(
154153
Numeric::percentage(val),
155154
"be within 0% and 100%",
@@ -161,7 +160,7 @@ fn check_pct_range(v: Value) -> Result<f64, String> {
161160

162161
fn check_amount(v: Value) -> Result<f64, String> {
163162
let val = check_pct(v)?;
164-
if val < zero() || val > one() {
163+
if val < 0.into() || val > 1.into() {
165164
Err(expected_to(
166165
Value::scalar(val * 100.),
167166
"be within 0 and 100",
@@ -177,10 +176,10 @@ fn check_channel(v: Value) -> Result<f64, String> {
177176
fn check_channel_range(v: Value) -> Result<f64, String> {
178177
let v = Numeric::try_from(v)?;
179178
let r = num2chan(&v)?;
180-
if r > 255. || r < zero() {
181-
Err(expected_to(v, "be within 0 and 255"))
182-
} else {
179+
if (0. ..=255.).contains(&r) {
183180
Ok(r)
181+
} else {
182+
Err(expected_to(v, "be within 0 and 255"))
184183
}
185184
}
186185
fn check_channel_pm(v: Value) -> Result<f64, String> {

rsass/src/sass/value.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use crate::input::SourcePos;
44
use crate::output::Format;
55
use crate::value::{BadOp, ListSeparator, Number, Numeric, Operator, Rgba};
66
use crate::{css, Error, Invalid, ScopeRef};
7-
use num_traits::Zero;
87
use std::fmt::{self, Write};
98

109
/// A sass value.
@@ -169,7 +168,7 @@ impl Value {
169168
let value = v.do_evaluate(scope, true)?;
170169
match (op, value) {
171170
(Operator::Not, css::Value::Numeric(v, _)) => {
172-
v.value.is_zero().into()
171+
(v.value == 0.into()).into()
173172
}
174173
(Operator::Not, css::Value::True) => css::Value::False,
175174
(Operator::Not, css::Value::False) => css::Value::True,

rsass/src/value/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ mod unitset;
1111

1212
pub use self::colors::{Color, Hsla, Hwba, RgbFormat, Rgba};
1313
pub use self::list_separator::ListSeparator;
14-
pub use self::number::{BadNumber, Number, Rational};
14+
pub use self::number::Number;
1515
pub use self::numeric::Numeric;
1616
pub use self::operator::{BadOp, Operator};
1717
pub use self::quotes::Quotes;

0 commit comments

Comments
 (0)