diff --git a/src/unit/mod.rs b/src/unit/mod.rs index b104035..4064179 100644 --- a/src/unit/mod.rs +++ b/src/unit/mod.rs @@ -96,12 +96,12 @@ pub(crate) enum Unit { Percent, /// Unknown unit - Unknown(String), + Unknown(Box), /// Unspecified unit None, /// Units multiplied together - Mul(Vec), + Mul(Box<[Unit]>), } #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub(crate) enum UnitKind { @@ -193,7 +193,7 @@ impl From for Unit { "dppx" => Unit::Dppx, "x" => Unit::X, "fr" => Unit::Fr, - _ => Unit::Unknown(unit), + _ => Unit::Unknown(unit.into_boxed_str()), } } } diff --git a/src/value/number/mod.rs b/src/value/number/mod.rs index ecc9a79..497c743 100644 --- a/src/value/number/mod.rs +++ b/src/value/number/mod.rs @@ -19,7 +19,7 @@ const PRECISION: usize = 10; #[derive(Clone, Eq, PartialEq, Ord)] pub(crate) enum Number { Machine(Rational64), - Big(BigRational), + Big(Box), } impl Number { @@ -27,8 +27,8 @@ impl Number { Number::Machine(val) } - pub const fn new_big(val: BigRational) -> Number { - Number::Big(val) + pub fn new_big(val: BigRational) -> Number { + Number::Big(Box::new(val)) } pub fn to_integer(&self) -> Integer { @@ -50,28 +50,28 @@ impl Number { pub fn round(&self) -> Self { match self { Self::Machine(val) => Self::Machine(val.round()), - Self::Big(val) => Self::Big(val.round()), + Self::Big(val) => Self::Big(Box::new(val.round())), } } pub fn ceil(&self) -> Self { match self { Self::Machine(val) => Self::Machine(val.ceil()), - Self::Big(val) => Self::Big(val.ceil()), + Self::Big(val) => Self::Big(Box::new(val.ceil())), } } pub fn floor(&self) -> Self { match self { Self::Machine(val) => Self::Machine(val.floor()), - Self::Big(val) => Self::Big(val.floor()), + Self::Big(val) => Self::Big(Box::new(val.floor())), } } pub fn abs(&self) -> Self { match self { Self::Machine(val) => Self::Machine(val.abs()), - Self::Big(val) => Self::Big(val.abs()), + Self::Big(val) => Self::Big(Box::new(val.abs())), } } @@ -191,7 +191,7 @@ macro_rules! from_integer { if let Ok(v) = i64::try_from(b) { Number::Machine(Rational64::from_integer(v)) } else { - Number::Big(BigRational::from_integer(BigInt::from(b))) + Number::Big(Box::new(BigRational::from_integer(BigInt::from(b)))) } } } @@ -217,7 +217,7 @@ impl From for Number { #[allow(clippy::fallible_impl_from)] impl From for Number { fn from(b: f64) -> Self { - Number::Big(BigRational::from_float(b).unwrap()) + Number::Big(Box::new(BigRational::from_float(b).unwrap())) } } @@ -310,7 +310,7 @@ impl PartialOrd for Number { Self::Big(val1) => match other { Self::Machine(val2) => { let tuple: (i64, i64) = (*val2).into(); - val1.partial_cmp(&BigRational::new_raw( + (**val1).partial_cmp(&BigRational::new_raw( BigInt::from(tuple.0), BigInt::from(tuple.1), )) @@ -332,29 +332,30 @@ impl Add for Number { None => { let tuple1: (i64, i64) = val1.into(); let tuple2: (i64, i64) = val2.into(); - Self::Big( + Self::Big(Box::new( BigRational::new_raw(BigInt::from(tuple1.0), BigInt::from(tuple1.1)) + BigRational::new_raw( BigInt::from(tuple2.0), BigInt::from(tuple2.1), ), - ) + )) } }, Self::Big(val2) => { let tuple: (i64, i64) = val1.into(); - Self::Big( - BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)) + val2, - ) + Self::Big(Box::new( + BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)) + *val2, + )) } }, Self::Big(val1) => match other { - Self::Big(val2) => Self::Big(val1 + val2), + Self::Big(val2) => Self::Big(Box::new(*val1 + *val2)), Self::Machine(val2) => { let tuple: (i64, i64) = val2.into(); - Self::Big( - val1 + BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)), - ) + Self::Big(Box::new( + (*val1) + + BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)), + )) } }, } @@ -372,29 +373,30 @@ impl Add<&Self> for Number { None => { let tuple1: (i64, i64) = val1.into(); let tuple2: (i64, i64) = (*val2).into(); - Self::Big( + Self::Big(Box::new( BigRational::new_raw(BigInt::from(tuple1.0), BigInt::from(tuple1.1)) + BigRational::new_raw( BigInt::from(tuple2.0), BigInt::from(tuple2.1), ), - ) + )) } }, Self::Big(val2) => { let tuple: (i64, i64) = val1.into(); - Self::Big( - BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)) + val2, - ) + Self::Big(Box::new( + BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)) + + *val2.clone(), + )) } }, Self::Big(val1) => match other { - Self::Big(val2) => Self::Big(val1 + val2), + Self::Big(val2) => Self::Big(Box::new(*val1 + *val2.clone())), Self::Machine(val2) => { let tuple: (i64, i64) = (*val2).into(); - Self::Big( - val1 + BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)), - ) + Self::Big(Box::new( + *val1 + BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)), + )) } }, } @@ -419,29 +421,29 @@ impl Sub for Number { None => { let tuple1: (i64, i64) = val1.into(); let tuple2: (i64, i64) = val2.into(); - Self::Big( + Self::Big(Box::new( BigRational::new_raw(BigInt::from(tuple1.0), BigInt::from(tuple1.1)) - BigRational::new_raw( BigInt::from(tuple2.0), BigInt::from(tuple2.1), ), - ) + )) } }, Self::Big(val2) => { let tuple: (i64, i64) = val1.into(); - Self::Big( - BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)) - val2, - ) + Self::Big(Box::new( + BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)) - *val2, + )) } }, Self::Big(val1) => match other { - Self::Big(val2) => Self::Big(val1 - val2), + Self::Big(val2) => Self::Big(Box::new(*val1 - *val2)), Self::Machine(val2) => { let tuple: (i64, i64) = val2.into(); - Self::Big( - val1 - BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)), - ) + Self::Big(Box::new( + *val1 - BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)), + )) } }, } @@ -466,29 +468,29 @@ impl Mul for Number { None => { let tuple1: (i64, i64) = val1.into(); let tuple2: (i64, i64) = val2.into(); - Self::Big( + Self::Big(Box::new( BigRational::new_raw(BigInt::from(tuple1.0), BigInt::from(tuple1.1)) * BigRational::new_raw( BigInt::from(tuple2.0), BigInt::from(tuple2.1), ), - ) + )) } }, Self::Big(val2) => { let tuple: (i64, i64) = val1.into(); - Self::Big( - BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)) * val2, - ) + Self::Big(Box::new( + BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)) * *val2, + )) } }, Self::Big(val1) => match other { - Self::Big(val2) => Self::Big(val1 * val2), + Self::Big(val2) => Self::Big(Box::new(*val1 * *val2)), Self::Machine(val2) => { let tuple: (i64, i64) = val2.into(); - Self::Big( - val1 * BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)), - ) + Self::Big(Box::new( + *val1 * BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)), + )) } }, } @@ -501,7 +503,7 @@ impl Mul for Number { fn mul(self, other: i64) -> Self { match self { Self::Machine(val1) => Self::Machine(val1 * other), - Self::Big(val1) => Self::Big(val1 * BigInt::from(other)), + Self::Big(val1) => Self::Big(Box::new(*val1 * BigInt::from(other))), } } } @@ -531,29 +533,29 @@ impl Div for Number { None => { let tuple1: (i64, i64) = val1.into(); let tuple2: (i64, i64) = val2.into(); - Self::Big( + Self::Big(Box::new( BigRational::new_raw(BigInt::from(tuple1.0), BigInt::from(tuple1.1)) / BigRational::new_raw( BigInt::from(tuple2.0), BigInt::from(tuple2.1), ), - ) + )) } }, Self::Big(val2) => { let tuple: (i64, i64) = val1.into(); - Self::Big( - BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)) / val2, - ) + Self::Big(Box::new( + BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)) / *val2, + )) } }, Self::Big(val1) => match other { - Self::Big(val2) => Self::Big(val1 / val2), + Self::Big(val2) => Self::Big(Box::new(*val1 / *val2)), Self::Machine(val2) => { let tuple: (i64, i64) = val2.into(); - Self::Big( - val1 / BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)), - ) + Self::Big(Box::new( + *val1 / BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)), + )) } }, } @@ -577,25 +579,25 @@ impl Rem for Number { Self::Machine(val2) => { let tuple1: (i64, i64) = val1.into(); let tuple2: (i64, i64) = val2.into(); - Self::Big( + Self::Big(Box::new( BigRational::new_raw(BigInt::from(tuple1.0), BigInt::from(tuple1.1)) % BigRational::new_raw(BigInt::from(tuple2.0), BigInt::from(tuple2.1)), - ) + )) } Self::Big(val2) => { let tuple: (i64, i64) = val1.into(); - Self::Big( - BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)) % val2, - ) + Self::Big(Box::new( + BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)) % *val2, + )) } }, Self::Big(val1) => match other { - Self::Big(val2) => Self::Big(val1 % val2), + Self::Big(val2) => Self::Big(Box::new(*val1 % *val2)), Self::Machine(val2) => { let tuple: (i64, i64) = val2.into(); - Self::Big( - val1 % BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)), - ) + Self::Big(Box::new( + *val1 % BigRational::new_raw(BigInt::from(tuple.0), BigInt::from(tuple.1)), + )) } }, } @@ -615,7 +617,7 @@ impl Neg for Number { fn neg(self) -> Self { match self { Self::Machine(v) => Self::Machine(-v), - Self::Big(v) => Self::Big(-v), + Self::Big(v) => Self::Big(Box::new(-*v)), } } } diff --git a/src/value/ops.rs b/src/value/ops.rs index 35d1ece..61b48e1 100644 --- a/src/value/ops.rs +++ b/src/value/ops.rs @@ -600,15 +600,19 @@ impl Value { Value::Dimension(num * num2, unit2) } else if unit2 == Unit::None { Value::Dimension(num * num2, unit) - } else if let Unit::Mul(mut u) = unit { - u.push(unit2); - Value::Dimension(num * num2, Unit::Mul(u)) + } else if let Unit::Mul(u) = unit { + let mut unit1 = u.into_vec(); + unit1.push(unit2); + Value::Dimension(num * num2, Unit::Mul(unit1.into_boxed_slice())) } else if let Unit::Mul(u2) = unit2 { let mut u = vec![unit]; - u.extend(u2); - Value::Dimension(num * num2, Unit::Mul(u)) + u.append(&mut u2.into_vec()); + Value::Dimension(num * num2, Unit::Mul(u.into_boxed_slice())) } else { - Value::Dimension(num * num2, Unit::Mul(vec![unit, unit2])) + Value::Dimension( + num * num2, + Unit::Mul(vec![unit, unit2].into_boxed_slice()), + ) } } _ => {