implement builtin function math.sqrt
This commit is contained in:
parent
53cf2816e0
commit
2265e7eb74
@ -115,7 +115,29 @@ fn pow(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
|||||||
|
|
||||||
fn sqrt(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
fn sqrt(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
args.max_args(1)?;
|
args.max_args(1)?;
|
||||||
todo!()
|
let number = args.get_err(0, "number")?;
|
||||||
|
|
||||||
|
Ok(match number {
|
||||||
|
Value::Dimension(Some(n), Unit::None, ..) => Value::Dimension(n.sqrt(), Unit::None, true),
|
||||||
|
v @ Value::Dimension(Some(..), ..) => {
|
||||||
|
return Err((
|
||||||
|
format!(
|
||||||
|
"$number: Expected {} to have no units.",
|
||||||
|
v.inspect(args.span())?
|
||||||
|
),
|
||||||
|
args.span(),
|
||||||
|
)
|
||||||
|
.into())
|
||||||
|
}
|
||||||
|
Value::Dimension(None, ..) => Value::Dimension(None, Unit::None, true),
|
||||||
|
v => {
|
||||||
|
return Err((
|
||||||
|
format!("$number: {} is not a number.", v.inspect(args.span())?),
|
||||||
|
args.span(),
|
||||||
|
)
|
||||||
|
.into())
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cos(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
fn cos(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
@ -165,6 +187,7 @@ pub(crate) fn declare(f: &mut Module) {
|
|||||||
f.insert_builtin("unit", unit);
|
f.insert_builtin("unit", unit);
|
||||||
f.insert_builtin("percentage", percentage);
|
f.insert_builtin("percentage", percentage);
|
||||||
f.insert_builtin("clamp", clamp);
|
f.insert_builtin("clamp", clamp);
|
||||||
|
f.insert_builtin("sqrt", sqrt);
|
||||||
#[cfg(feature = "random")]
|
#[cfg(feature = "random")]
|
||||||
f.insert_builtin("random", random);
|
f.insert_builtin("random", random);
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ grass input.scss
|
|||||||
clippy::unknown_clippy_lints,
|
clippy::unknown_clippy_lints,
|
||||||
clippy::replace_consts,
|
clippy::replace_consts,
|
||||||
clippy::single_match,
|
clippy::single_match,
|
||||||
|
clippy::float_arithmetic,
|
||||||
|
|
||||||
// temporarily allowed while under heavy development.
|
// temporarily allowed while under heavy development.
|
||||||
// eventually these allows should be refactored away
|
// eventually these allows should be refactored away
|
||||||
|
@ -8,7 +8,9 @@ use std::{
|
|||||||
|
|
||||||
use num_bigint::BigInt;
|
use num_bigint::BigInt;
|
||||||
use num_rational::{BigRational, Rational64};
|
use num_rational::{BigRational, Rational64};
|
||||||
use num_traits::{CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, Num, One, Signed, Zero};
|
use num_traits::{
|
||||||
|
CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, Num, One, Signed, ToPrimitive, Zero,
|
||||||
|
};
|
||||||
|
|
||||||
use integer::Integer;
|
use integer::Integer;
|
||||||
|
|
||||||
@ -106,6 +108,18 @@ impl Number {
|
|||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::cast_precision_loss)]
|
||||||
|
pub fn sqrt(self) -> Option<Self> {
|
||||||
|
Some(match self {
|
||||||
|
Number::Small(n) => Number::Big(Box::new(BigRational::from_float(
|
||||||
|
((*n.numer() as f64) / (*n.denom() as f64)).sqrt(),
|
||||||
|
)?)),
|
||||||
|
Number::Big(n) => Number::Big(Box::new(BigRational::from_float(
|
||||||
|
((n.numer().to_f64()?) / (n.denom().to_f64()?)).sqrt(),
|
||||||
|
)?)),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Number {
|
impl Default for Number {
|
||||||
|
@ -38,3 +38,43 @@ error!(
|
|||||||
"@use 'sass:math';\na {\n color: math.clamp(0mm, 1cm, 2);\n}\n",
|
"@use 'sass:math';\na {\n color: math.clamp(0mm, 1cm, 2);\n}\n",
|
||||||
"Error: $min has unit mm but $max is unitless. Arguments must all have units or all be unitless."
|
"Error: $min has unit mm but $max is unitless. Arguments must all have units or all be unitless."
|
||||||
);
|
);
|
||||||
|
test!(
|
||||||
|
sqrt_zero,
|
||||||
|
"@use 'sass:math';\na {\n color: math.sqrt(0);\n}\n",
|
||||||
|
"a {\n color: 0;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
sqrt_small_positive,
|
||||||
|
"@use 'sass:math';\na {\n color: math.sqrt(99);\n}\n",
|
||||||
|
"a {\n color: 9.9498743711;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
sqrt_small_negative,
|
||||||
|
"@use 'sass:math';\na {\n color: math.sqrt(-99);\n}\n",
|
||||||
|
"a {\n color: NaN;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
sqrt_big_positive,
|
||||||
|
"@use 'sass:math';\na {\n color: math.sqrt(9999999999999999999999999999999999999999999999999);\n}\n",
|
||||||
|
"a {\n color: 3162277660168379038695424;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
sqrt_big_negative,
|
||||||
|
"@use 'sass:math';\na {\n color: math.sqrt(-9999999999999999999999999999999999999999999999999);\n}\n",
|
||||||
|
"a {\n color: NaN;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
sqrt_irrational,
|
||||||
|
"@use 'sass:math';\na {\n color: math.sqrt(2);\n}\n",
|
||||||
|
"a {\n color: 1.4142135624;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
sqrt_of_nan,
|
||||||
|
"@use 'sass:math';\na {\n color: math.sqrt((0 / 0));\n}\n",
|
||||||
|
"a {\n color: NaN;\n}\n"
|
||||||
|
);
|
||||||
|
error!(
|
||||||
|
sqrt_with_units,
|
||||||
|
"@use 'sass:math';\na {\n color: math.sqrt(1px);\n}\n",
|
||||||
|
"Error: $number: Expected 1px to have no units."
|
||||||
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user