make better use of num traits
This commit is contained in:
parent
0e0b01f595
commit
0be8828bf0
@ -1,5 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use num_traits::One;
|
||||
|
||||
use super::Builtin;
|
||||
use crate::color::Color;
|
||||
use crate::common::QuoteKind;
|
||||
@ -46,7 +48,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
hue,
|
||||
saturation,
|
||||
luminance,
|
||||
Number::from(1),
|
||||
Number::one(),
|
||||
)))
|
||||
} else {
|
||||
let hue = match arg!(args, 0, "hue") {
|
||||
@ -64,7 +66,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
let alpha = match arg!(
|
||||
args,
|
||||
3,
|
||||
"alpha" = Value::Dimension(Number::from(1), Unit::None)
|
||||
"alpha" = Value::Dimension(Number::one(), Unit::None)
|
||||
) {
|
||||
Value::Dimension(n, Unit::None) => n,
|
||||
Value::Dimension(n, Unit::Percent) => n / Number::from(100),
|
||||
@ -120,7 +122,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
hue,
|
||||
saturation,
|
||||
luminance,
|
||||
Number::from(1),
|
||||
Number::one(),
|
||||
)))
|
||||
} else {
|
||||
let hue = match arg!(args, 0, "hue") {
|
||||
@ -138,7 +140,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
let alpha = match arg!(
|
||||
args,
|
||||
3,
|
||||
"alpha" = Value::Dimension(Number::from(1), Unit::None)
|
||||
"alpha" = Value::Dimension(Number::one(), Unit::None)
|
||||
) {
|
||||
Value::Dimension(n, Unit::None) => n,
|
||||
Value::Dimension(n, Unit::Percent) => n / Number::from(100),
|
||||
@ -280,7 +282,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
}
|
||||
v => return Err(format!("$color: {} is not a color.", v).into()),
|
||||
};
|
||||
Ok(Value::Color(color.desaturate(Number::from(1))))
|
||||
Ok(Value::Color(color.desaturate(Number::one())))
|
||||
}),
|
||||
);
|
||||
f.insert(
|
||||
|
@ -1,5 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use num_traits::{One, Signed, Zero};
|
||||
|
||||
use super::Builtin;
|
||||
use crate::color::Color;
|
||||
use crate::common::QuoteKind;
|
||||
@ -84,10 +86,10 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
|
||||
if red.is_some() || green.is_some() || blue.is_some() {
|
||||
return Ok(Value::Color(Color::from_rgba(
|
||||
color.red() + red.unwrap_or(Number::from(0)),
|
||||
color.green() + green.unwrap_or(Number::from(0)),
|
||||
color.blue() + blue.unwrap_or(Number::from(0)),
|
||||
color.alpha() + alpha.unwrap_or(Number::from(0)),
|
||||
color.red() + red.unwrap_or(Number::zero()),
|
||||
color.green() + green.unwrap_or(Number::zero()),
|
||||
color.blue() + blue.unwrap_or(Number::zero()),
|
||||
color.alpha() + alpha.unwrap_or(Number::zero()),
|
||||
)));
|
||||
}
|
||||
|
||||
@ -104,10 +106,10 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
// Color::as_hsla() returns more exact values than Color::hue(), etc.
|
||||
let (this_hue, this_saturation, this_luminance, this_alpha) = color.as_hsla();
|
||||
return Ok(Value::Color(Color::from_hsla(
|
||||
this_hue + hue.unwrap_or(Number::from(0)),
|
||||
this_saturation + saturation.unwrap_or(Number::from(0)),
|
||||
this_luminance + luminance.unwrap_or(Number::from(0)),
|
||||
this_alpha + alpha.unwrap_or(Number::from(0)),
|
||||
this_hue + hue.unwrap_or(Number::zero()),
|
||||
this_saturation + saturation.unwrap_or(Number::zero()),
|
||||
this_luminance + luminance.unwrap_or(Number::zero()),
|
||||
this_alpha + alpha.unwrap_or(Number::zero()),
|
||||
)));
|
||||
}
|
||||
|
||||
@ -154,23 +156,23 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
return Ok(Value::Color(Color::from_rgba(
|
||||
scale(
|
||||
color.red(),
|
||||
red.unwrap_or(Number::from(0)),
|
||||
red.unwrap_or(Number::zero()),
|
||||
Number::from(255),
|
||||
),
|
||||
scale(
|
||||
color.green(),
|
||||
green.unwrap_or(Number::from(0)),
|
||||
green.unwrap_or(Number::zero()),
|
||||
Number::from(255),
|
||||
),
|
||||
scale(
|
||||
color.blue(),
|
||||
blue.unwrap_or(Number::from(0)),
|
||||
blue.unwrap_or(Number::zero()),
|
||||
Number::from(255),
|
||||
),
|
||||
scale(
|
||||
color.alpha(),
|
||||
alpha.unwrap_or(Number::from(0)),
|
||||
Number::from(1),
|
||||
alpha.unwrap_or(Number::zero()),
|
||||
Number::one(),
|
||||
),
|
||||
)));
|
||||
}
|
||||
@ -182,28 +184,24 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
// Color::as_hsla() returns more exact values than Color::hue(), etc.
|
||||
let (this_hue, this_saturation, this_luminance, this_alpha) = color.as_hsla();
|
||||
return Ok(Value::Color(Color::from_hsla(
|
||||
scale(this_hue, Number::from(0), Number::from(360)),
|
||||
scale(this_hue, Number::zero(), Number::from(360)),
|
||||
scale(
|
||||
this_saturation,
|
||||
saturation.unwrap_or(Number::from(0)),
|
||||
Number::from(1),
|
||||
saturation.unwrap_or(Number::zero()),
|
||||
Number::one(),
|
||||
),
|
||||
scale(
|
||||
this_luminance,
|
||||
luminance.unwrap_or(Number::from(0)),
|
||||
Number::from(1),
|
||||
),
|
||||
scale(
|
||||
this_alpha,
|
||||
alpha.unwrap_or(Number::from(0)),
|
||||
Number::from(1),
|
||||
luminance.unwrap_or(Number::zero()),
|
||||
Number::one(),
|
||||
),
|
||||
scale(this_alpha, alpha.unwrap_or(Number::zero()), Number::one()),
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(Value::Color(if let Some(a) = alpha {
|
||||
let temp_alpha = color.alpha();
|
||||
color.with_alpha(scale(temp_alpha, a, Number::from(1)))
|
||||
color.with_alpha(scale(temp_alpha, a, Number::one()))
|
||||
} else {
|
||||
color
|
||||
}))
|
||||
@ -223,8 +221,8 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
}
|
||||
|
||||
fn scale(val: Number, by: Number, max: Number) -> Number {
|
||||
if by == Number::from(0) {
|
||||
if by.is_zero() {
|
||||
return val;
|
||||
}
|
||||
val.clone() + (if by > Number::from(0) { max - val } else { val }) * by
|
||||
val.clone() + (if by.is_positive() { max - val } else { val }) * by
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use num_traits::One;
|
||||
|
||||
use super::Builtin;
|
||||
use crate::color::Color;
|
||||
use crate::unit::Unit;
|
||||
@ -50,7 +52,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
None => return Err("Missing element $red.".into()),
|
||||
};
|
||||
|
||||
let color = Color::from_rgba(red, green, blue, Number::from(1));
|
||||
let color = Color::from_rgba(red, green, blue, Number::one());
|
||||
|
||||
Ok(Value::Color(color))
|
||||
} else if args.len() == 2 {
|
||||
@ -109,7 +111,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
let alpha = match arg!(
|
||||
args,
|
||||
3,
|
||||
"alpha" = Value::Dimension(Number::from(1), Unit::None)
|
||||
"alpha" = Value::Dimension(Number::one(), Unit::None)
|
||||
) {
|
||||
Value::Dimension(n, Unit::None) => n,
|
||||
Value::Dimension(n, Unit::Percent) => n / Number::from(100),
|
||||
@ -168,7 +170,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
None => return Err("Missing element $red.".into()),
|
||||
};
|
||||
|
||||
let color = Color::from_rgba(red, green, blue, Number::from(1));
|
||||
let color = Color::from_rgba(red, green, blue, Number::one());
|
||||
|
||||
Ok(Value::Color(color))
|
||||
} else if args.len() == 2 {
|
||||
@ -227,7 +229,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
let alpha = match arg!(
|
||||
args,
|
||||
3,
|
||||
"alpha" = Value::Dimension(Number::from(1), Unit::None)
|
||||
"alpha" = Value::Dimension(Number::one(), Unit::None)
|
||||
) {
|
||||
Value::Dimension(n, Unit::None) => n,
|
||||
Value::Dimension(n, Unit::Percent) => n / Number::from(100),
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use num_traits::cast::ToPrimitive;
|
||||
use num_traits::{One, Signed, ToPrimitive, Zero};
|
||||
|
||||
use super::Builtin;
|
||||
use crate::common::{ListSeparator, QuoteKind};
|
||||
@ -14,7 +14,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
max_args!(args, 1);
|
||||
let len = match arg!(args, 0, "list") {
|
||||
Value::List(v, _) => Number::from(v.len()),
|
||||
_ => Number::from(1),
|
||||
_ => Number::one(),
|
||||
};
|
||||
Ok(Value::Dimension(len, Unit::None))
|
||||
}),
|
||||
@ -32,7 +32,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
v => return Err(format!("$n: {} is not a number.", v).into()),
|
||||
};
|
||||
|
||||
if n == Number::from(0) {
|
||||
if n.is_zero() {
|
||||
return Err("$n: List index may not be 0.".into());
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
return Err(format!("$n: {} is not an int.", n).into());
|
||||
}
|
||||
|
||||
if n > Number::from(0) {
|
||||
if n.is_positive() {
|
||||
Ok(list[n.to_integer().to_usize().unwrap() - 1].clone())
|
||||
} else {
|
||||
Ok(list[list.len() - n.abs().to_integer().to_usize().unwrap()].clone())
|
||||
@ -83,7 +83,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
v => return Err(format!("$n: {} is not a number.", v).into()),
|
||||
};
|
||||
|
||||
if n == Number::from(0) {
|
||||
if n.is_zero() {
|
||||
return Err("$n: List index may not be 0.".into());
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
|
||||
let val = arg!(args, 2, "value");
|
||||
|
||||
if n > Number::from(0) {
|
||||
if n.is_positive() {
|
||||
list[n.to_integer().to_usize().unwrap() - 1] = val;
|
||||
} else {
|
||||
list[len - n.abs().to_integer().to_usize().unwrap()] = val;
|
||||
|
@ -1,8 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use num_bigint::BigInt;
|
||||
use num_traits::cast::ToPrimitive;
|
||||
use num_traits::sign::Signed;
|
||||
use num_traits::{Signed, ToPrimitive, Zero};
|
||||
|
||||
use super::Builtin;
|
||||
use crate::common::QuoteKind;
|
||||
@ -35,7 +34,10 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
Box::new(|args, _| {
|
||||
max_args!(args, 1);
|
||||
match arg!(args, 0, "string") {
|
||||
Value::Ident(i, _) => Ok(Value::Dimension(Number::from(i.chars().count()), Unit::None)),
|
||||
Value::Ident(i, _) => Ok(Value::Dimension(
|
||||
Number::from(i.chars().count()),
|
||||
Unit::None,
|
||||
)),
|
||||
v => Err(format!("$string: {} is not a string.", v).into()),
|
||||
}
|
||||
}),
|
||||
@ -73,10 +75,10 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
Value::Dimension(n, Unit::None) if n.is_decimal() => {
|
||||
return Err(format!("{} is not an int.", n).into())
|
||||
}
|
||||
Value::Dimension(n, Unit::None) if n.to_integer().is_positive() => {
|
||||
Value::Dimension(n, Unit::None) if n.is_positive() => {
|
||||
n.to_integer().to_usize().unwrap()
|
||||
}
|
||||
Value::Dimension(n, Unit::None) if n == Number::from(0) => 1_usize,
|
||||
Value::Dimension(n, Unit::None) if n.is_zero() => 1_usize,
|
||||
Value::Dimension(n, Unit::None) if n < -Number::from(str_len) => 1_usize,
|
||||
Value::Dimension(n, Unit::None) => (BigInt::from(str_len + 1) + n.to_integer())
|
||||
.to_usize()
|
||||
@ -90,10 +92,10 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
Value::Dimension(n, Unit::None) if n.is_decimal() => {
|
||||
return Err(format!("{} is not an int.", n).into())
|
||||
}
|
||||
Value::Dimension(n, Unit::None) if n.to_integer().is_positive() => {
|
||||
Value::Dimension(n, Unit::None) if n.is_positive() => {
|
||||
n.to_integer().to_usize().unwrap()
|
||||
}
|
||||
Value::Dimension(n, Unit::None) if n == Number::from(0) => 0_usize,
|
||||
Value::Dimension(n, Unit::None) if n.is_zero() => 0_usize,
|
||||
Value::Dimension(n, Unit::None) if n < -Number::from(str_len) => 0_usize,
|
||||
Value::Dimension(n, Unit::None) => (BigInt::from(str_len + 1) + n.to_integer())
|
||||
.to_usize()
|
||||
@ -197,13 +199,13 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
.collect::<String>()
|
||||
};
|
||||
|
||||
let string = if index > Number::from(0) {
|
||||
let string = if index.is_positive() {
|
||||
insert(
|
||||
index.to_integer().to_usize().unwrap().min(len + 1) - 1,
|
||||
s1,
|
||||
&substr,
|
||||
)
|
||||
} else if index == Number::from(0) {
|
||||
} else if index.is_zero() {
|
||||
insert(0, s1, &substr)
|
||||
} else {
|
||||
let idx = index.abs().to_integer().to_usize().unwrap();
|
||||
|
@ -20,7 +20,7 @@ use std::fmt::{self, Display};
|
||||
use crate::value::Number;
|
||||
pub(crate) use name::ColorName;
|
||||
|
||||
use num_traits::cast::ToPrimitive;
|
||||
use num_traits::{One, Signed, ToPrimitive, Zero};
|
||||
|
||||
mod name;
|
||||
|
||||
@ -149,8 +149,8 @@ impl Color {
|
||||
($channel:ident) => {
|
||||
let $channel = if $channel > Number::from(255) {
|
||||
Number::from(255)
|
||||
} else if $channel < Number::from(0) {
|
||||
Number::from(0)
|
||||
} else if $channel.is_negative() {
|
||||
Number::zero()
|
||||
} else {
|
||||
$channel
|
||||
};
|
||||
@ -161,10 +161,10 @@ impl Color {
|
||||
clamp!(green);
|
||||
clamp!(blue);
|
||||
|
||||
let alpha = if alpha > Number::from(1) {
|
||||
Number::from(1)
|
||||
} else if alpha < Number::from(0) {
|
||||
Number::from(0)
|
||||
let alpha = if alpha > Number::one() {
|
||||
Number::one()
|
||||
} else if alpha.is_negative() {
|
||||
Number::zero()
|
||||
} else {
|
||||
alpha
|
||||
};
|
||||
@ -190,7 +190,7 @@ impl Color {
|
||||
/// <https://github.com/sass/dart-sass/blob/0d0270cb12a9ac5cce73a4d0785fecb00735feee/lib/src/functions/color.dart#L718>
|
||||
pub fn mix(self, other: &Color, weight: Number) -> Self {
|
||||
let weight = clamp!(weight, 0, 100);
|
||||
let normalized_weight = weight.clone() * Number::from(2) - Number::from(1);
|
||||
let normalized_weight = weight.clone() * Number::from(2) - Number::one();
|
||||
let alpha_distance = self.alpha() - other.alpha();
|
||||
|
||||
let combined_weight1 =
|
||||
@ -198,16 +198,16 @@ impl Color {
|
||||
normalized_weight
|
||||
} else {
|
||||
(normalized_weight.clone() + alpha_distance.clone())
|
||||
/ (Number::from(1) + normalized_weight * alpha_distance)
|
||||
/ (Number::one() + normalized_weight * alpha_distance)
|
||||
};
|
||||
let weight1 = (combined_weight1 + Number::from(1)) / Number::from(2);
|
||||
let weight2 = Number::from(1) - weight1.clone();
|
||||
let weight1 = (combined_weight1 + Number::one()) / Number::from(2);
|
||||
let weight2 = Number::one() - weight1.clone();
|
||||
|
||||
Color::from_rgba(
|
||||
self.red() * weight1.clone() + other.red() * weight2.clone(),
|
||||
self.green() * weight1.clone() + other.green() * weight2.clone(),
|
||||
self.blue() * weight1 + other.blue() * weight2,
|
||||
self.alpha() * weight.clone() + other.alpha() * (Number::from(1) - weight),
|
||||
self.alpha() * weight.clone() + other.alpha() * (Number::one() - weight),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -227,7 +227,7 @@ impl Color {
|
||||
let min = red.clone().min(green.clone().min(blue.clone()));
|
||||
let max = red.clone().max(green.clone().max(blue.clone()));
|
||||
if min == max {
|
||||
return Number::from(0);
|
||||
return Number::zero();
|
||||
}
|
||||
|
||||
let mut hue = if blue == max {
|
||||
@ -238,7 +238,7 @@ impl Color {
|
||||
(green - blue) / (max - min)
|
||||
};
|
||||
|
||||
if hue < Number::from(0) {
|
||||
if hue.is_negative() {
|
||||
hue += Number::from(360);
|
||||
}
|
||||
|
||||
@ -259,12 +259,12 @@ impl Color {
|
||||
let max = red.max(green.max(blue));
|
||||
|
||||
if min == max {
|
||||
return Number::from(0);
|
||||
return Number::zero();
|
||||
}
|
||||
|
||||
let d = max.clone() - min.clone();
|
||||
let mm = max + min;
|
||||
let s = d / if mm > Number::from(1) {
|
||||
let s = d / if mm > Number::one() {
|
||||
Number::from(2) - mm
|
||||
} else {
|
||||
mm
|
||||
@ -300,11 +300,11 @@ impl Color {
|
||||
let lightness = (min.clone() + max.clone()) / Number::from(2);
|
||||
|
||||
let saturation = if min == max {
|
||||
Number::from(0)
|
||||
Number::zero()
|
||||
} else {
|
||||
let d = max.clone() - min.clone();
|
||||
let mm = max.clone() + min.clone();
|
||||
d / if mm > Number::from(1) {
|
||||
d / if mm > Number::one() {
|
||||
Number::from(2) - mm
|
||||
} else {
|
||||
mm
|
||||
@ -312,7 +312,7 @@ impl Color {
|
||||
};
|
||||
|
||||
let mut hue = if min == max {
|
||||
Number::from(0)
|
||||
Number::zero()
|
||||
} else if blue == max {
|
||||
Number::from(4) + (red - green) / (max - min)
|
||||
} else if green == max {
|
||||
@ -321,7 +321,7 @@ impl Color {
|
||||
(green - blue) / (max - min)
|
||||
};
|
||||
|
||||
if hue < Number::from(0) {
|
||||
if hue.is_negative() {
|
||||
hue += Number::from(360);
|
||||
}
|
||||
|
||||
@ -361,7 +361,7 @@ impl Color {
|
||||
hue % Number::from(360)
|
||||
} else if hue < Number::from(-360) {
|
||||
Number::from(360) + hue % Number::from(360)
|
||||
} else if hue < Number::from(0) {
|
||||
} else if hue.is_negative() {
|
||||
Number::from(360) + clamp!(hue, -360, 360)
|
||||
} else {
|
||||
hue
|
||||
@ -378,7 +378,7 @@ impl Color {
|
||||
alpha.clone(),
|
||||
);
|
||||
|
||||
if saturation.clone() == Number::from(0) {
|
||||
if saturation.is_zero() {
|
||||
let luminance = if luminance > Number::from(100) {
|
||||
Number::from(100)
|
||||
} else {
|
||||
@ -388,8 +388,8 @@ impl Color {
|
||||
let repr = repr(&val, &val, &val, &alpha);
|
||||
return Color::new_hsla(val.clone(), val.clone(), val, alpha, hsla, repr);
|
||||
}
|
||||
let temporary_1 = if luminance.clone() < Number::ratio(1, 2) {
|
||||
luminance.clone() * (Number::from(1) + saturation)
|
||||
let temporary_1 = if luminance < Number::ratio(1, 2) {
|
||||
luminance.clone() * (Number::one() + saturation)
|
||||
} else {
|
||||
luminance.clone() + saturation.clone() - luminance.clone() * saturation
|
||||
};
|
||||
@ -401,10 +401,10 @@ impl Color {
|
||||
|
||||
macro_rules! clamp_temp {
|
||||
($temp:ident) => {
|
||||
if $temp > Number::from(1) {
|
||||
$temp -= Number::from(1);
|
||||
} else if $temp < Number::from(0) {
|
||||
$temp += Number::from(1);
|
||||
if $temp > Number::one() {
|
||||
$temp -= Number::one();
|
||||
} else if $temp.is_negative() {
|
||||
$temp += Number::one();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -415,10 +415,10 @@ impl Color {
|
||||
|
||||
macro_rules! channel {
|
||||
($name:ident, $temp:ident, $temp1:ident, $temp2:ident) => {
|
||||
let $name = if Number::from(6) * $temp.clone() < Number::from(1) {
|
||||
let $name = if Number::from(6) * $temp.clone() < Number::one() {
|
||||
$temp2.clone()
|
||||
+ ($temp1.clone() - $temp2.clone()) * Number::from(6) * $temp.clone()
|
||||
} else if Number::from(2) * $temp.clone() < Number::from(1) {
|
||||
} else if Number::from(2) * $temp.clone() < Number::one() {
|
||||
$temp1.clone()
|
||||
} else if Number::from(3) * $temp.clone() < Number::from(2) {
|
||||
$temp2.clone()
|
||||
@ -440,7 +440,7 @@ impl Color {
|
||||
}
|
||||
|
||||
pub fn invert(&self, weight: Number) -> Self {
|
||||
if weight == Number::from(0) {
|
||||
if weight.is_zero() {
|
||||
return self.clone();
|
||||
}
|
||||
let red = Number::from(u8::max_value()) - self.red();
|
||||
@ -466,7 +466,7 @@ impl Color {
|
||||
impl Color {
|
||||
pub fn alpha(&self) -> Number {
|
||||
let a = self.rgba.alpha();
|
||||
if a > Number::from(1) {
|
||||
if a > Number::one() {
|
||||
a / Number::from(255)
|
||||
} else {
|
||||
a
|
||||
@ -512,7 +512,7 @@ fn repr(red: &Number, green: &Number, blue: &Number, alpha: &Number) -> String {
|
||||
($channel:ident) => {
|
||||
let $channel = if $channel > &Number::from(255) {
|
||||
255_u8
|
||||
} else if $channel < &Number::from(0) {
|
||||
} else if $channel.is_negative() {
|
||||
0_u8
|
||||
} else {
|
||||
$channel.clone().round().to_integer().to_u8().unwrap()
|
||||
@ -524,7 +524,7 @@ fn repr(red: &Number, green: &Number, blue: &Number, alpha: &Number) -> String {
|
||||
into_u8!(green);
|
||||
into_u8!(blue);
|
||||
|
||||
if alpha < &Number::from(1) {
|
||||
if alpha < &Number::one() {
|
||||
format!("rgba({}, {}, {}, {})", red, green, blue, alpha)
|
||||
} else if let Ok(c) = ColorName::try_from([red, green, blue]) {
|
||||
format!("{}", c)
|
||||
|
@ -208,10 +208,10 @@ impl<'a> Lexer<'a> {
|
||||
self.buf.next();
|
||||
self.pos.next_char();
|
||||
if let TokenKind::Ident(s) = self.lex_ident() {
|
||||
if !s.is_empty() {
|
||||
TokenKind::AtRule(AtRuleKind::from(s.as_ref()))
|
||||
} else {
|
||||
if s.is_empty() {
|
||||
TokenKind::Error("Expected identifier.".into())
|
||||
} else {
|
||||
TokenKind::AtRule(AtRuleKind::from(s.as_ref()))
|
||||
}
|
||||
} else {
|
||||
TokenKind::Error("Expected identifier.".into())
|
||||
|
@ -416,7 +416,7 @@ impl<'a> StyleSheetParser<'a> {
|
||||
AtRule::If(cond, yes, no) => {
|
||||
if Value::from_tokens(
|
||||
&mut cond.into_iter().peekable(),
|
||||
&mut GLOBAL_SCOPE.with(|s| s.borrow().clone()),
|
||||
&GLOBAL_SCOPE.with(|s| s.borrow().clone()),
|
||||
&Selector::new(),
|
||||
)?.is_true()? {
|
||||
rules.extend(yes);
|
||||
@ -453,7 +453,7 @@ impl<'a> StyleSheetParser<'a> {
|
||||
AtRule::If(cond, yes, no) => {
|
||||
if Value::from_tokens(
|
||||
&mut cond.into_iter().peekable(),
|
||||
&mut GLOBAL_SCOPE.with(|s| s.borrow().clone()),
|
||||
&GLOBAL_SCOPE.with(|s| s.borrow().clone()),
|
||||
&Selector::new(),
|
||||
)?
|
||||
.is_true()?
|
||||
|
@ -6,6 +6,7 @@ use std::collections::HashMap;
|
||||
use std::f64::consts::PI;
|
||||
use std::string::ToString;
|
||||
|
||||
use num_traits::One;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::value::Number;
|
||||
@ -13,17 +14,17 @@ use crate::value::Number;
|
||||
pub(crate) static UNIT_CONVERSION_TABLE: Lazy<HashMap<String, HashMap<String, Number>>> =
|
||||
Lazy::new(|| {
|
||||
let mut from_in = HashMap::new();
|
||||
from_in.insert("in".to_string(), Number::from(1));
|
||||
from_in.insert("cm".to_string(), Number::from(1) / Number::from(2.54));
|
||||
from_in.insert("in".to_string(), Number::one());
|
||||
from_in.insert("cm".to_string(), Number::one() / Number::from(2.54));
|
||||
from_in.insert("pc".to_string(), Number::ratio(1, 6));
|
||||
from_in.insert("mm".to_string(), Number::from(1) / Number::from(25.4));
|
||||
from_in.insert("q".to_string(), Number::from(1) / Number::from(101.6));
|
||||
from_in.insert("mm".to_string(), Number::one() / Number::from(25.4));
|
||||
from_in.insert("q".to_string(), Number::one() / Number::from(101.6));
|
||||
from_in.insert("pt".to_string(), Number::ratio(1, 72));
|
||||
from_in.insert("px".to_string(), Number::ratio(1, 96));
|
||||
|
||||
let mut from_cm = HashMap::new();
|
||||
from_cm.insert("in".to_string(), Number::from(2.54));
|
||||
from_cm.insert("cm".to_string(), Number::from(1));
|
||||
from_cm.insert("cm".to_string(), Number::one());
|
||||
from_cm.insert("pc".to_string(), Number::from(2.54) / Number::from(6));
|
||||
from_cm.insert("mm".to_string(), Number::ratio(1, 10));
|
||||
from_cm.insert("q".to_string(), Number::ratio(1, 40));
|
||||
@ -33,7 +34,7 @@ pub(crate) static UNIT_CONVERSION_TABLE: Lazy<HashMap<String, HashMap<String, Nu
|
||||
let mut from_pc = HashMap::new();
|
||||
from_pc.insert("in".to_string(), Number::from(6));
|
||||
from_pc.insert("cm".to_string(), Number::from(6) / Number::from(2.54));
|
||||
from_pc.insert("pc".to_string(), Number::from(1));
|
||||
from_pc.insert("pc".to_string(), Number::one());
|
||||
from_pc.insert("mm".to_string(), Number::from(6) / Number::from(25.4));
|
||||
from_pc.insert("q".to_string(), Number::from(6) / Number::from(101.6));
|
||||
from_pc.insert("pt".to_string(), Number::ratio(1, 12));
|
||||
@ -43,7 +44,7 @@ pub(crate) static UNIT_CONVERSION_TABLE: Lazy<HashMap<String, HashMap<String, Nu
|
||||
from_mm.insert("in".to_string(), Number::from(25.4));
|
||||
from_mm.insert("cm".to_string(), Number::from(10));
|
||||
from_mm.insert("pc".to_string(), Number::from(25.4) / Number::from(6));
|
||||
from_mm.insert("mm".to_string(), Number::from(1));
|
||||
from_mm.insert("mm".to_string(), Number::one());
|
||||
from_mm.insert("q".to_string(), Number::ratio(1, 4));
|
||||
from_mm.insert("pt".to_string(), Number::from(25.4) / Number::from(72));
|
||||
from_mm.insert("px".to_string(), Number::from(25.4) / Number::from(96));
|
||||
@ -53,7 +54,7 @@ pub(crate) static UNIT_CONVERSION_TABLE: Lazy<HashMap<String, HashMap<String, Nu
|
||||
from_q.insert("cm".to_string(), Number::from(40));
|
||||
from_q.insert("pc".to_string(), Number::from(101.6) / Number::from(6));
|
||||
from_q.insert("mm".to_string(), Number::from(4));
|
||||
from_q.insert("q".to_string(), Number::from(1));
|
||||
from_q.insert("q".to_string(), Number::one());
|
||||
from_q.insert("pt".to_string(), Number::from(101.6) / Number::from(72));
|
||||
from_q.insert("px".to_string(), Number::from(101.6) / Number::from(96));
|
||||
|
||||
@ -63,7 +64,7 @@ pub(crate) static UNIT_CONVERSION_TABLE: Lazy<HashMap<String, HashMap<String, Nu
|
||||
from_pt.insert("pc".to_string(), Number::from(12));
|
||||
from_pt.insert("mm".to_string(), Number::from(72) / Number::from(25.4));
|
||||
from_pt.insert("q".to_string(), Number::from(72) / Number::from(101.6));
|
||||
from_pt.insert("pt".to_string(), Number::from(1));
|
||||
from_pt.insert("pt".to_string(), Number::one());
|
||||
from_pt.insert("px".to_string(), Number::ratio(3, 4));
|
||||
|
||||
let mut from_px = HashMap::new();
|
||||
@ -73,62 +74,62 @@ pub(crate) static UNIT_CONVERSION_TABLE: Lazy<HashMap<String, HashMap<String, Nu
|
||||
from_px.insert("mm".to_string(), Number::from(96) / Number::from(25.4));
|
||||
from_px.insert("q".to_string(), Number::from(96) / Number::from(101.6));
|
||||
from_px.insert("pt".to_string(), Number::ratio(4, 3));
|
||||
from_px.insert("px".to_string(), Number::from(1));
|
||||
from_px.insert("px".to_string(), Number::one());
|
||||
|
||||
let mut from_deg = HashMap::new();
|
||||
from_deg.insert("deg".to_string(), Number::from(1));
|
||||
from_deg.insert("deg".to_string(), Number::one());
|
||||
from_deg.insert("grad".to_string(), Number::ratio(9, 10));
|
||||
from_deg.insert("rad".to_string(), Number::from(180) / Number::from(PI));
|
||||
from_deg.insert("turn".to_string(), Number::from(360));
|
||||
|
||||
let mut from_grad = HashMap::new();
|
||||
from_grad.insert("deg".to_string(), Number::ratio(10, 9));
|
||||
from_grad.insert("grad".to_string(), Number::from(1));
|
||||
from_grad.insert("grad".to_string(), Number::one());
|
||||
from_grad.insert("rad".to_string(), Number::from(200) / Number::from(PI));
|
||||
from_grad.insert("turn".to_string(), Number::from(400));
|
||||
|
||||
let mut from_rad = HashMap::new();
|
||||
from_rad.insert("deg".to_string(), Number::from(PI) / Number::from(180));
|
||||
from_rad.insert("grad".to_string(), Number::from(PI) / Number::from(200));
|
||||
from_rad.insert("rad".to_string(), Number::from(1));
|
||||
from_rad.insert("rad".to_string(), Number::one());
|
||||
from_rad.insert("turn".to_string(), Number::from(2.0 * PI));
|
||||
|
||||
let mut from_turn = HashMap::new();
|
||||
from_turn.insert("deg".to_string(), Number::ratio(1, 360));
|
||||
from_turn.insert("grad".to_string(), Number::ratio(1, 400));
|
||||
from_turn.insert("rad".to_string(), Number::from(1) / Number::from(2.0 * PI));
|
||||
from_turn.insert("turn".to_string(), Number::from(1));
|
||||
from_turn.insert("rad".to_string(), Number::one() / Number::from(2.0 * PI));
|
||||
from_turn.insert("turn".to_string(), Number::one());
|
||||
|
||||
let mut from_s = HashMap::new();
|
||||
from_s.insert("s".to_string(), Number::from(1));
|
||||
from_s.insert("s".to_string(), Number::one());
|
||||
from_s.insert("ms".to_string(), Number::ratio(1, 1000));
|
||||
|
||||
let mut from_ms = HashMap::new();
|
||||
from_ms.insert("s".to_string(), Number::from(1000));
|
||||
from_ms.insert("ms".to_string(), Number::from(1));
|
||||
from_ms.insert("ms".to_string(), Number::one());
|
||||
|
||||
let mut from_hz = HashMap::new();
|
||||
from_hz.insert("Hz".to_string(), Number::from(1));
|
||||
from_hz.insert("Hz".to_string(), Number::one());
|
||||
from_hz.insert("kHz".to_string(), Number::from(1000));
|
||||
|
||||
let mut from_khz = HashMap::new();
|
||||
from_khz.insert("Hz".to_string(), Number::ratio(1, 1000));
|
||||
from_khz.insert("kHz".to_string(), Number::from(1));
|
||||
from_khz.insert("kHz".to_string(), Number::one());
|
||||
|
||||
let mut from_dpi = HashMap::new();
|
||||
from_dpi.insert("dpi".to_string(), Number::from(1));
|
||||
from_dpi.insert("dpi".to_string(), Number::one());
|
||||
from_dpi.insert("dpcm".to_string(), Number::from(2.54));
|
||||
from_dpi.insert("dppx".to_string(), Number::from(96));
|
||||
|
||||
let mut from_dpcm = HashMap::new();
|
||||
from_dpcm.insert("dpi".to_string(), Number::from(1) / Number::from(2.54));
|
||||
from_dpcm.insert("dpcm".to_string(), Number::from(1));
|
||||
from_dpcm.insert("dpi".to_string(), Number::one() / Number::from(2.54));
|
||||
from_dpcm.insert("dpcm".to_string(), Number::one());
|
||||
from_dpcm.insert("dppx".to_string(), Number::from(96) / Number::from(2.54));
|
||||
|
||||
let mut from_dppx = HashMap::new();
|
||||
from_dppx.insert("dpi".to_string(), Number::ratio(1, 96));
|
||||
from_dppx.insert("dpcm".to_string(), Number::from(2.54) / Number::from(96));
|
||||
from_dppx.insert("dppx".to_string(), Number::from(1));
|
||||
from_dppx.insert("dppx".to_string(), Number::one());
|
||||
|
||||
let mut m = HashMap::new();
|
||||
m.insert("in".to_string(), from_in);
|
||||
|
@ -102,7 +102,7 @@ impl Value {
|
||||
match self {
|
||||
&Value::Null => true,
|
||||
Value::Ident(i, QuoteKind::None) if i.is_empty() => true,
|
||||
_ => false
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,9 @@ use std::ops::{
|
||||
|
||||
use num_bigint::BigInt;
|
||||
use num_rational::BigRational;
|
||||
use num_traits::sign::Signed;
|
||||
use num_traits::{Num, One, Signed, Zero};
|
||||
|
||||
use crate::error::SassError;
|
||||
|
||||
const PRECISION: usize = 10;
|
||||
|
||||
@ -57,6 +59,63 @@ impl Number {
|
||||
}
|
||||
}
|
||||
|
||||
impl Zero for Number {
|
||||
fn zero() -> Self {
|
||||
Number::from(0)
|
||||
}
|
||||
|
||||
fn is_zero(&self) -> bool {
|
||||
self.val.is_zero()
|
||||
}
|
||||
}
|
||||
|
||||
impl One for Number {
|
||||
fn one() -> Self {
|
||||
Number::from(1)
|
||||
}
|
||||
|
||||
fn is_one(&self) -> bool {
|
||||
self.val.is_one()
|
||||
}
|
||||
}
|
||||
|
||||
impl Num for Number {
|
||||
type FromStrRadixErr = SassError;
|
||||
fn from_str_radix(_str: &str, _radix: u32) -> Result<Self, Self::FromStrRadixErr> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Signed for Number {
|
||||
fn abs(&self) -> Self {
|
||||
self.abs()
|
||||
}
|
||||
|
||||
fn abs_sub(&self, other: &Self) -> Self {
|
||||
Number {
|
||||
val: self.val.abs_sub(&other.val),
|
||||
}
|
||||
}
|
||||
|
||||
fn signum(&self) -> Self {
|
||||
if self.is_zero() {
|
||||
Self::zero()
|
||||
} else if self.is_positive() {
|
||||
Self::one()
|
||||
} else {
|
||||
-Self::one()
|
||||
}
|
||||
}
|
||||
|
||||
fn is_positive(&self) -> bool {
|
||||
self.val.is_positive()
|
||||
}
|
||||
|
||||
fn is_negative(&self) -> bool {
|
||||
self.val.is_negative()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::LowerHex for Number {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{:0>2x}", self.val.to_integer())
|
||||
|
@ -293,7 +293,7 @@ impl Value {
|
||||
TokenKind::Keyword(Keyword::Through(s)) => Ok(Value::Ident(s, QuoteKind::None)),
|
||||
TokenKind::Keyword(Keyword::To(s)) => Ok(Value::Ident(s, QuoteKind::None)),
|
||||
TokenKind::AtRule(_) => Err("expected \";\".".into()),
|
||||
TokenKind::Error(e) => return Err(e),
|
||||
TokenKind::Error(e) => Err(e),
|
||||
TokenKind::Symbol(Symbol::BackSlash) => {
|
||||
if let Some(tok) = toks.next() {
|
||||
match tok.kind {
|
||||
|
Loading…
x
Reference in New Issue
Block a user