implement builtin function nth
This commit is contained in:
parent
fb84361fae
commit
dd1c1e5b06
@ -1,5 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use num_traits::cast::ToPrimitive;
|
||||
|
||||
use super::Builtin;
|
||||
use crate::unit::Unit;
|
||||
use crate::value::{Number, Value};
|
||||
@ -16,4 +18,41 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
|
||||
Ok(Value::Dimension(len, Unit::None))
|
||||
}),
|
||||
);
|
||||
f.insert(
|
||||
"nth".to_owned(),
|
||||
Box::new(|args, _| {
|
||||
max_args!(args, 2);
|
||||
let list = match arg!(args, 0, "list") {
|
||||
Value::List(v, _) => v,
|
||||
_ => return Err("Missing argument $list.".into()),
|
||||
};
|
||||
let n = match arg!(args, 1, "n") {
|
||||
Value::Dimension(num, _) => num,
|
||||
v => return Err(format!("$n: {} is not a number.", v).into()),
|
||||
};
|
||||
|
||||
if n == Number::from(0) {
|
||||
return Err("$n: List index may not be 0.".into());
|
||||
}
|
||||
|
||||
if n.abs() > Number::from(list.len()) {
|
||||
return Err(format!(
|
||||
"$n: Invalid index {} for a list with {} elements.",
|
||||
n,
|
||||
list.len()
|
||||
)
|
||||
.into());
|
||||
}
|
||||
|
||||
if n.is_decimal() {
|
||||
return Err(format!("$n: {} is not an int.", n).into());
|
||||
}
|
||||
|
||||
if n > Number::from(0) {
|
||||
Ok(list[n.to_integer().to_usize().unwrap() - 1].clone())
|
||||
} else {
|
||||
Ok(list[list.len() - n.abs().to_integer().to_usize().unwrap()].clone())
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -28,25 +28,25 @@ impl Number {
|
||||
Number::new(BigRational::new(a.into(), b.into()))
|
||||
}
|
||||
|
||||
pub fn round(self) -> Self {
|
||||
pub fn round(&self) -> Self {
|
||||
Number {
|
||||
val: self.val.round(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ceil(self) -> Self {
|
||||
pub fn ceil(&self) -> Self {
|
||||
Number {
|
||||
val: self.val.ceil(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn floor(self) -> Self {
|
||||
pub fn floor(&self) -> Self {
|
||||
Number {
|
||||
val: self.val.floor(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn abs(self) -> Self {
|
||||
pub fn abs(&self) -> Self {
|
||||
Number {
|
||||
val: self.val.abs(),
|
||||
}
|
||||
|
@ -18,3 +18,18 @@ test!(
|
||||
"a {\n color: length((1, 2, 3, 4, 5));\n}\n",
|
||||
"a {\n color: 5;\n}\n"
|
||||
);
|
||||
test!(
|
||||
nth_space_separated,
|
||||
"a {\n color: nth(a b c, 1);\n}\n",
|
||||
"a {\n color: a;\n}\n"
|
||||
);
|
||||
test!(
|
||||
nth_negative_index,
|
||||
"a {\n color: nth(a b c, -2);\n}\n",
|
||||
"a {\n color: b;\n}\n"
|
||||
);
|
||||
test!(
|
||||
nth_comma_separated,
|
||||
"a {\n color: nth((a, b, c), 3);\n}\n",
|
||||
"a {\n color: c;\n}\n"
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user