From 3c691be264a126db21b8bc3d10eb6bf672ed2db2 Mon Sep 17 00:00:00 2001 From: David Cook Date: Fri, 15 May 2020 23:06:00 -0500 Subject: [PATCH 1/3] Parse and add variants for BigInt numbers --- Cargo.toml | 2 + src/css/value.rs | 8 ++- src/css/valueformat.rs | 3 + src/parser/value.rs | 140 +++++++++++++++++++++++++++++++++------- src/sass/value.rs | 15 ++++- src/value/number.rs | 106 ++++++++++++++++++++---------- tests/fuzz_cases.rs | 29 +++++++-- tests/rust_functions.rs | 8 ++- 8 files changed, 243 insertions(+), 68 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5b97bf35a..c78c4a4e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,8 @@ spectest = ["yaml-rust", "deunicode", "hrx-get", "regex"] bytecount = "0.6.0" lazy_static = "1.0" nom = "5.0.0" +num-bigint = { version = "0.2.1", default-features = false, features = ["std"] } +num-integer = "0.1.42" num-rational = { version = "0.2.1", default-features = false } num-traits = "^0.2.0" rand = "0.7.0" diff --git a/src/css/value.rs b/src/css/value.rs index 553240665..76937674c 100644 --- a/src/css/value.rs +++ b/src/css/value.rs @@ -4,6 +4,7 @@ use crate::functions::SassFunction; use crate::ordermap::OrderMap; use crate::output::{Format, Formatted}; use crate::value::{ListSeparator, Number, Operator, Quotes, Rgba, Unit}; +use num_bigint::BigInt; use num_rational::Rational; use std::convert::TryFrom; @@ -24,7 +25,10 @@ pub enum Value { /// /// The boolean flag is true for calculated values and false for /// literal values. - Numeric(Number, Unit, bool), + Numeric(Number, Unit, bool), + /// A rational value with a Unit and flags, similar to Numeric, but with + /// support for arbitrarily large numbers. + NumericBig(Number, Unit, bool), Color(Rgba, Option), Null, True, @@ -41,7 +45,7 @@ pub enum Value { } impl Value { - pub fn scalar>(v: T) -> Self { + pub fn scalar>>(v: T) -> Self { Value::Numeric(v.into(), Unit::None, false) } pub fn bool(v: bool) -> Self { diff --git a/src/css/valueformat.rs b/src/css/valueformat.rs index 20045f5dc..8ad015532 100644 --- a/src/css/valueformat.rs +++ b/src/css/valueformat.rs @@ -43,6 +43,9 @@ impl<'a> Display for Formatted<'a, Value> { Value::Numeric(ref num, ref unit, _) => { write!(out, "{}{}", num.format(self.format), unit) } + Value::NumericBig(ref num, ref unit, _) => { + write!(out, "{}{}", num.format(self.format), unit) + } Value::Color(ref rgba, ref name) => { if let Some(ref name) = *name { name.fmt(out) diff --git a/src/parser/value.rs b/src/parser/value.rs index a138508d1..dbea84869 100644 --- a/src/parser/value.rs +++ b/src/parser/value.rs @@ -8,19 +8,21 @@ use super::util::{opt_spacelike, spacelike2}; use super::{input_to_string, sass_string}; use crate::ordermap::OrderMap; use crate::sass::{SassString, Value}; -use crate::value::{ListSeparator, Number, Operator, Rgba}; +use crate::value::{ListSeparator, Number, Operator, Rgba, Unit}; use nom::branch::alt; use nom::bytes::complete::{tag, tag_no_case}; use nom::character::complete::{ alphanumeric1, multispace0, multispace1, one_of, }; -use nom::combinator::{map, map_res, not, opt, peek, recognize, value}; +use nom::combinator::{map, map_opt, map_res, not, opt, peek, recognize, value}; use nom::multi::{ fold_many0, fold_many1, many0, many_m_n, separated_nonempty_list, }; use nom::sequence::{delimited, pair, preceded, terminated, tuple}; use nom::IResult; -use num_rational::Rational; +use num_bigint::BigInt; +use num_rational::{Ratio, Rational}; +use num_traits::{One, Zero}; use std::str::from_utf8; pub fn value_expression(input: &[u8]) -> IResult<&[u8], Value> { @@ -294,19 +296,13 @@ fn bracket_list(input: &[u8]) -> IResult<&[u8], Value> { )) } +fn sign_prefix(input: &[u8]) -> IResult<&[u8], Option<&[u8]>> { + opt(alt((tag("-"), tag("+"))))(input) +} + fn number(input: &[u8]) -> IResult<&[u8], Value> { - let (input, (sign, (lead_zero, num), unit)) = tuple(( - opt(alt((tag("-"), tag("+")))), - alt(( - map(pair(decimal_integer, opt(decimal_decimals)), |(n, d)| { - (true, if let Some(d) = d { n + d } else { n }) - }), - map(decimal_decimals, |dec| (false, dec)), - )), - unit, - ))(input)?; - Ok(( - input, + fn make_numeric(tuple: (Option<&[u8]>, (bool, Ratio), Unit)) -> Value { + let (sign, (lead_zero, num), unit) = tuple; Value::Numeric( Number { value: if sign == Some(b"-") { -num } else { num }, @@ -314,31 +310,129 @@ fn number(input: &[u8]) -> IResult<&[u8], Value> { lead_zero, }, unit, + ) + }; + + fn make_numeric_big(tuple: (Option<&[u8]>, (bool, Ratio), Unit)) -> Value { + let (sign, (lead_zero, num), unit) = tuple; + Value::NumericBig( + Number { + value: if sign == Some(b"-") { -num } else { num }, + plus_sign: sign == Some(b"+"), + lead_zero, + }, + unit, + ) + }; + + alt(( + map( + tuple(( + sign_prefix, + map(pair(decimal_integer, decimal_decimals), |(n, d)| { + (true, n + d) + }), + unit, + )), + make_numeric, ), - )) + map( + tuple(( + sign_prefix, + map(pair(decimal_integer_big, decimal_decimals_big), |(n, d)| { + (true, n + d) + }), + unit, + )), + make_numeric_big, + ), + map( + tuple(( + sign_prefix, + map(decimal_decimals, |dec| (false, dec)), + unit, + )), + make_numeric, + ), + map( + tuple(( + sign_prefix, + map(decimal_decimals_big, |dec| (false, dec)), + unit, + )), + make_numeric_big, + ), + map( + tuple(( + sign_prefix, + map(decimal_integer, |int| (true, int)), + unit, + )), + make_numeric, + ), + map( + tuple(( + sign_prefix, + map(decimal_integer_big, |int| (true, int)), + unit, + )), + make_numeric_big, + ), + ))(input) } pub fn decimal_integer(input: &[u8]) -> IResult<&[u8], Rational> { + map_opt( + fold_many1( + // Note: We should use bytes directly, one_of returns a char. + one_of("0123456789"), + Some(0isize), + |r, d| r?.checked_mul(10)?.checked_add(isize::from(d as u8 - b'0')), + ), + |opt_int| opt_int.map(Rational::from_integer), + )(input) +} + +pub fn decimal_integer_big(input: &[u8]) -> IResult<&[u8], Ratio> { map( fold_many1( // Note: We should use bytes directly, one_of returns a char. one_of("0123456789"), - 0, - |r, d| r * 10 + isize::from(d as u8 - b'0'), + BigInt::zero(), + |r, d| r * 10 + BigInt::from(d as u8 - b'0'), ), - Rational::from_integer, + Ratio::from_integer, )(input) } pub fn decimal_decimals(input: &[u8]) -> IResult<&[u8], Rational> { + map_opt( + preceded( + tag("."), + fold_many1( + one_of("0123456789"), + Some((0isize, 1isize)), + |opt_pair, d| { + let (r, n) = opt_pair?; + Some((r.checked_mul(10)?.checked_add(isize::from(d as i8 - b'0' as i8))?, n.checked_mul(10)?)) + } + ), + ), + |opt_pair| opt_pair.map(|(r, d)| Rational::new(r, d)), + )(input) +} + +pub fn decimal_decimals_big(input: &[u8]) -> IResult<&[u8], Ratio> { map( preceded( tag("."), - fold_many1(one_of("0123456789"), (0, 1), |(r, n), d| { - (r * 10 + isize::from(d as i8 - b'0' as i8), n * 10) - }), + fold_many1( + one_of("0123456789"), + (BigInt::zero(), BigInt::one()), + |(r, n), d| (r * 10 + BigInt::from(d as i8 - b'0' as i8), n * 10) + ), ), - |(r, d)| Rational::new(r, d), + |(r, d)| Ratio::new(r, d), )(input) } diff --git a/src/sass/value.rs b/src/sass/value.rs index 3380185d5..06ca2f5bf 100644 --- a/src/sass/value.rs +++ b/src/sass/value.rs @@ -5,6 +5,7 @@ use crate::ordermap::OrderMap; use crate::sass::{CallArgs, SassString}; use crate::value::{ListSeparator, Number, Operator, Quotes, Rgba, Unit}; use crate::variablescope::Scope; +use num_bigint::BigInt; use num_rational::Rational; use num_traits::Zero; @@ -20,7 +21,11 @@ pub enum Value { List(Vec, ListSeparator, bool, bool), /// A Numeric value is a rational value with a Unit (which may be /// Unit::None) and flags. - Numeric(Number, Unit), + Numeric(Number, Unit), + /// A NumericBig value is a rational value with a Unit (which may be + /// Unit::None) and flags. The numerator and denominator of the value + /// may be arbitrarily large. + NumericBig(Number, Unit), /// "(a/b) and a/b differs semantically. Parens means the value /// should be evaluated numerically if possible, without parens / /// is not allways division. @@ -96,6 +101,7 @@ impl Value { pub fn evaluate(&self, scope: &dyn Scope) -> Result { self.do_evaluate(scope, false) } + pub fn do_evaluate( &self, scope: &dyn Scope, @@ -162,6 +168,13 @@ impl Value { } Ok(css::Value::Numeric(num, unit.clone(), arithmetic)) } + Value::NumericBig(ref num, ref unit) => { + let mut num = num.clone(); + if arithmetic { + num.lead_zero = true; + } + Ok(css::Value::NumericBig(num, unit.clone(), arithmetic)) + } Value::Map(ref m) => { let items = m.iter() .map(|&(ref k, ref v)| -> Result<(css::Value, css::Value), Error> { diff --git a/src/value/number.rs b/src/value/number.rs index 3d0158bd6..6a7f4ad5e 100644 --- a/src/value/number.rs +++ b/src/value/number.rs @@ -1,5 +1,6 @@ use crate::output::{Format, Formatted}; -use num_rational::Rational; +use num_integer::Integer; +use num_rational::Ratio; use num_traits::{Signed, Zero}; use std::fmt::{self, Write}; use std::ops::{Add, Div, Mul, Neg, Rem, Sub}; @@ -10,13 +11,19 @@ use std::ops::{Add, Div, Mul, Neg, Rem, Sub}; /// to show a leading plus sign and/or leading zero (for values /// between -1 and 1) is included. #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] -pub struct Number { - pub value: Rational, +pub struct Number +where + N: Clone + Integer + Signed, +{ + pub value: Ratio, pub plus_sign: bool, pub lead_zero: bool, } -impl Number { +impl Number +where + N: Clone + Integer + Signed, +{ /// Computes the absolute value of the number, retaining the flags. pub fn abs(self) -> Self { Number { @@ -25,14 +32,17 @@ impl Number { lead_zero: self.lead_zero, } } + /// Returns true if the number is an integer. pub fn is_integer(&self) -> bool { self.value.is_integer() } + /// Converts to an integer, rounding towards zero. - pub fn to_integer(&self) -> isize { + pub fn to_integer(&self) -> N { self.value.to_integer() } + pub fn format(&self, format: Format) -> Formatted { Formatted { value: self, @@ -41,11 +51,12 @@ impl Number { } } -impl From for Number +impl From for Number where - T: Into, + T: Into>, + N: Clone + Integer + Signed, { - fn from(value: T) -> Number { + fn from(value: T) -> Number { Number { value: value.into(), plus_sign: false, @@ -54,44 +65,67 @@ where } } -impl Add for Number { - type Output = Number; +impl Add for Number +where + N: Clone + Integer + Signed, +{ + type Output = Number; fn add(self, rhs: Self) -> Self::Output { Number::from(self.value + rhs.value) } } -impl<'a> Div for &'a Number { - type Output = Number; + +impl<'a, N> Div for &'a Number +where + N: Clone + Integer + Signed, +{ + type Output = Number; fn div(self, rhs: Self) -> Self::Output { - Number::from(self.value / rhs.value) + Number::from(&self.value / &rhs.value) } } -impl<'a> Mul for &'a Number { - type Output = Number; + +impl<'a, N> Mul for &'a Number +where + N: Clone + Integer + Signed, +{ + type Output = Number; fn mul(self, rhs: Self) -> Self::Output { - Number::from(self.value * rhs.value) + Number::from(&self.value * &rhs.value) } } -impl<'a> Rem for &'a Number { - type Output = Number; + +impl<'a, N> Rem for &'a Number +where + N: Clone + Integer + Signed, +{ + type Output = Number; fn rem(self, rhs: Self) -> Self::Output { - Number::from(self.value % rhs.value) + Number::from(&self.value % &rhs.value) } } -impl<'a> Neg for &'a Number { - type Output = Number; - fn neg(self) -> Number { - Number::from(-self.value) + +impl<'a, N> Neg for &'a Number +where + N: Clone + Integer + Signed, +{ + type Output = Number; + fn neg(self) -> Number { + Number::from(-&self.value) } } -impl<'a> Sub for &'a Number { - type Output = Number; +impl<'a, N> Sub for &'a Number +where + N: Clone + Integer + Signed, +{ + type Output = Number; fn sub(self, rhs: Self) -> Self::Output { - Number::from(self.value - rhs.value) + Number::from(&self.value - &rhs.value) } } -impl Zero for Number { + +impl Zero for Number { fn zero() -> Self { Number::from(0) } @@ -100,8 +134,12 @@ impl Zero for Number { } } -impl<'a> fmt::Display for Formatted<'a, Number> { +impl<'a, N> fmt::Display for Formatted<'a, Number> +where + N: Clone + fmt::Display + Integer + Signed + From, +{ fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result { + let ten: N = 10i8.into(); let mut frac = self.value.value.fract(); let mut whole = self.value.value.to_integer().abs(); @@ -113,7 +151,7 @@ impl<'a> fmt::Display for Formatted<'a, Number> { if !frac.is_zero() { for _ in 0..(self.format.precision - 1) { - frac *= 10; + frac = frac * &ten; write!(dec, "{}", frac.to_integer().abs())?; frac = frac.fract(); if frac.is_zero() { @@ -121,13 +159,13 @@ impl<'a> fmt::Display for Formatted<'a, Number> { } } if !frac.is_zero() { - let end = (frac * 10).round().abs().to_integer(); - if end == 10 { + let end = (frac * &ten).round().abs().to_integer(); + if end == ten { loop { match dec.pop() { Some('9') => continue, None => { - whole += 1; + whole = whole + N::one(); break; } Some(c) => { @@ -136,7 +174,7 @@ impl<'a> fmt::Display for Formatted<'a, Number> { } } } - } else if end == 0 { + } else if end.is_zero() { loop { match dec.pop() { Some('0') => continue, @@ -160,7 +198,7 @@ impl<'a> fmt::Display for Formatted<'a, Number> { } let skip_zero = self.format.is_compressed() || !self.value.lead_zero; - if !(whole == 0 && skip_zero && !dec.is_empty()) { + if !(whole.is_zero() && skip_zero && !dec.is_empty()) { write!(out, "{}", whole)?; } diff --git a/tests/fuzz_cases.rs b/tests/fuzz_cases.rs index 2e179463c..7c35471eb 100644 --- a/tests/fuzz_cases.rs +++ b/tests/fuzz_cases.rs @@ -1,10 +1,27 @@ -use rsass::{compile_scss, output}; +use rsass::{compile_scss, compile_value, output}; + +const FORMAT: output::Format = output::Format { + style: output::Style::Compressed, + precision: 5, +}; #[test] fn bad_escape() { - let format = output::Format { - style: output::Style::Compressed, - precision: 5, - }; - assert!(compile_scss(b"\\d00000", format).is_err()); + assert!(compile_scss(b"\\d00000", FORMAT).is_err()); +} + +#[test] +fn decimal_integer_overflow() { + assert_eq!( + compile_value(b"2000000000000000000000000000000000000", FORMAT).unwrap(), + b"2000000000000000000000000000000000000".to_vec(), + ); +} + +#[test] +fn decimal_fraction_overflow() { + assert_eq!( + compile_value(b"0.2000000000000000000000000000000000000", FORMAT).unwrap(), + b".2", + ); } diff --git a/tests/rust_functions.rs b/tests/rust_functions.rs index 72ada422e..774a6216a 100644 --- a/tests/rust_functions.rs +++ b/tests/rust_functions.rs @@ -47,8 +47,12 @@ fn simple_function() { } #[cfg(test)] -fn avg(a: Number, b: Number) -> Number { - Number::from((a.value + b.value) / 2) +fn avg(a: Number, b: Number) -> Number +where + N: Clone + num_integer::Integer + num_traits::Signed + From +{ + let two: N = 2i8.into(); + Number::from((a.value + b.value) / two) } #[test] From 3bf62e127915b0b413669ae154488e38a3d85136 Mon Sep 17 00:00:00 2001 From: David Cook Date: Fri, 15 May 2020 23:33:19 -0500 Subject: [PATCH 2/3] Refactor number parser --- src/parser/value.rs | 107 +++++++++++++++----------------------------- 1 file changed, 35 insertions(+), 72 deletions(-) diff --git a/src/parser/value.rs b/src/parser/value.rs index dbea84869..e33cd0924 100644 --- a/src/parser/value.rs +++ b/src/parser/value.rs @@ -8,7 +8,7 @@ use super::util::{opt_spacelike, spacelike2}; use super::{input_to_string, sass_string}; use crate::ordermap::OrderMap; use crate::sass::{SassString, Value}; -use crate::value::{ListSeparator, Number, Operator, Rgba, Unit}; +use crate::value::{ListSeparator, Number, Operator, Rgba}; use nom::branch::alt; use nom::bytes::complete::{tag, tag_no_case}; use nom::character::complete::{ @@ -300,85 +300,48 @@ fn sign_prefix(input: &[u8]) -> IResult<&[u8], Option<&[u8]>> { opt(alt((tag("-"), tag("+"))))(input) } -fn number(input: &[u8]) -> IResult<&[u8], Value> { - fn make_numeric(tuple: (Option<&[u8]>, (bool, Ratio), Unit)) -> Value { - let (sign, (lead_zero, num), unit) = tuple; - Value::Numeric( - Number { - value: if sign == Some(b"-") { -num } else { num }, - plus_sign: sign == Some(b"+"), - lead_zero, - }, - unit, - ) - }; - - fn make_numeric_big(tuple: (Option<&[u8]>, (bool, Ratio), Unit)) -> Value { - let (sign, (lead_zero, num), unit) = tuple; - Value::NumericBig( - Number { - value: if sign == Some(b"-") { -num } else { num }, - plus_sign: sign == Some(b"+"), - lead_zero, - }, - unit, - ) - }; +enum AnyRatio { + Machine(Ratio), + Big(Ratio), +} - alt(( - map( - tuple(( - sign_prefix, +fn number(input: &[u8]) -> IResult<&[u8], Value> { + map( + tuple(( + sign_prefix, + alt(( map(pair(decimal_integer, decimal_decimals), |(n, d)| { - (true, n + d) + (true, AnyRatio::Machine(n + d)) }), - unit, - )), - make_numeric, - ), - map( - tuple(( - sign_prefix, map(pair(decimal_integer_big, decimal_decimals_big), |(n, d)| { - (true, n + d) + (true, AnyRatio::Big(n + d)) }), - unit, - )), - make_numeric_big, - ), - map( - tuple(( - sign_prefix, - map(decimal_decimals, |dec| (false, dec)), - unit, + map(decimal_decimals, |dec| (false, AnyRatio::Machine(dec))), + map(decimal_decimals_big, |dec| (false, AnyRatio::Big(dec))), + map(decimal_integer, |int| (true, AnyRatio::Machine(int))), + map(decimal_integer_big, |int| (true, AnyRatio::Big(int))), )), - make_numeric, - ), - map( - tuple(( - sign_prefix, - map(decimal_decimals_big, |dec| (false, dec)), - unit, - )), - make_numeric_big, - ), - map( - tuple(( - sign_prefix, - map(decimal_integer, |int| (true, int)), + unit, + )), + |(sign, (lead_zero, num), unit)| match num { + AnyRatio::Machine(num) => Value::Numeric( + Number { + value: if sign == Some(b"-") { -num } else { num }, + plus_sign: sign == Some(b"+"), + lead_zero, + }, unit, - )), - make_numeric, - ), - map( - tuple(( - sign_prefix, - map(decimal_integer_big, |int| (true, int)), + ), + AnyRatio::Big(num) => Value::NumericBig( + Number { + value: if sign == Some(b"-") { -num } else { num }, + plus_sign: sign == Some(b"+"), + lead_zero, + }, unit, - )), - make_numeric_big, - ), - ))(input) + ), + }, + )(input) } pub fn decimal_integer(input: &[u8]) -> IResult<&[u8], Rational> { From 483c1c35ea001f74185a4d9b669c6b2a8f487b9b Mon Sep 17 00:00:00 2001 From: Rasmus Kaj Date: Sat, 19 Sep 2020 20:19:16 +0200 Subject: [PATCH 3/3] Rustfmt. --- src/parser/value.rs | 27 +++++++++++++++++++-------- tests/fuzz_cases.rs | 6 ++++-- tests/rust_functions.rs | 2 +- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/parser/value.rs b/src/parser/value.rs index e33cd0924..cb658086f 100644 --- a/src/parser/value.rs +++ b/src/parser/value.rs @@ -14,7 +14,9 @@ use nom::bytes::complete::{tag, tag_no_case}; use nom::character::complete::{ alphanumeric1, multispace0, multispace1, one_of, }; -use nom::combinator::{map, map_opt, map_res, not, opt, peek, recognize, value}; +use nom::combinator::{ + map, map_opt, map_res, not, opt, peek, recognize, value, +}; use nom::multi::{ fold_many0, fold_many1, many0, many_m_n, separated_nonempty_list, }; @@ -313,9 +315,10 @@ fn number(input: &[u8]) -> IResult<&[u8], Value> { map(pair(decimal_integer, decimal_decimals), |(n, d)| { (true, AnyRatio::Machine(n + d)) }), - map(pair(decimal_integer_big, decimal_decimals_big), |(n, d)| { - (true, AnyRatio::Big(n + d)) - }), + map( + pair(decimal_integer_big, decimal_decimals_big), + |(n, d)| (true, AnyRatio::Big(n + d)), + ), map(decimal_decimals, |dec| (false, AnyRatio::Machine(dec))), map(decimal_decimals_big, |dec| (false, AnyRatio::Big(dec))), map(decimal_integer, |int| (true, AnyRatio::Machine(int))), @@ -350,7 +353,9 @@ pub fn decimal_integer(input: &[u8]) -> IResult<&[u8], Rational> { // Note: We should use bytes directly, one_of returns a char. one_of("0123456789"), Some(0isize), - |r, d| r?.checked_mul(10)?.checked_add(isize::from(d as u8 - b'0')), + |r, d| { + r?.checked_mul(10)?.checked_add(isize::from(d as u8 - b'0')) + }, ), |opt_int| opt_int.map(Rational::from_integer), )(input) @@ -377,8 +382,12 @@ pub fn decimal_decimals(input: &[u8]) -> IResult<&[u8], Rational> { Some((0isize, 1isize)), |opt_pair, d| { let (r, n) = opt_pair?; - Some((r.checked_mul(10)?.checked_add(isize::from(d as i8 - b'0' as i8))?, n.checked_mul(10)?)) - } + Some(( + r.checked_mul(10)? + .checked_add(isize::from(d as i8 - b'0' as i8))?, + n.checked_mul(10)?, + )) + }, ), ), |opt_pair| opt_pair.map(|(r, d)| Rational::new(r, d)), @@ -392,7 +401,9 @@ pub fn decimal_decimals_big(input: &[u8]) -> IResult<&[u8], Ratio> { fold_many1( one_of("0123456789"), (BigInt::zero(), BigInt::one()), - |(r, n), d| (r * 10 + BigInt::from(d as i8 - b'0' as i8), n * 10) + |(r, n), d| { + (r * 10 + BigInt::from(d as i8 - b'0' as i8), n * 10) + }, ), ), |(r, d)| Ratio::new(r, d), diff --git a/tests/fuzz_cases.rs b/tests/fuzz_cases.rs index 7c35471eb..da35149e0 100644 --- a/tests/fuzz_cases.rs +++ b/tests/fuzz_cases.rs @@ -13,7 +13,8 @@ fn bad_escape() { #[test] fn decimal_integer_overflow() { assert_eq!( - compile_value(b"2000000000000000000000000000000000000", FORMAT).unwrap(), + compile_value(b"2000000000000000000000000000000000000", FORMAT) + .unwrap(), b"2000000000000000000000000000000000000".to_vec(), ); } @@ -21,7 +22,8 @@ fn decimal_integer_overflow() { #[test] fn decimal_fraction_overflow() { assert_eq!( - compile_value(b"0.2000000000000000000000000000000000000", FORMAT).unwrap(), + compile_value(b"0.2000000000000000000000000000000000000", FORMAT) + .unwrap(), b".2", ); } diff --git a/tests/rust_functions.rs b/tests/rust_functions.rs index 774a6216a..55cdb2f84 100644 --- a/tests/rust_functions.rs +++ b/tests/rust_functions.rs @@ -49,7 +49,7 @@ fn simple_function() { #[cfg(test)] fn avg(a: Number, b: Number) -> Number where - N: Clone + num_integer::Integer + num_traits::Signed + From + N: Clone + num_integer::Integer + num_traits::Signed + From, { let two: N = 2i8.into(); Number::from((a.value + b.value) / two)