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