From 82ffd0dddeac4639802db80b6fa754ff0a447f6f Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Wed, 17 Jun 2020 05:24:42 -0400 Subject: [PATCH] arglists are lists too --- src/builtin/list.rs | 12 +++++------- src/parse/mod.rs | 18 ++---------------- src/value/mod.rs | 1 + tests/arglist.rs | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 23 deletions(-) create mode 100644 tests/arglist.rs diff --git a/src/builtin/list.rs b/src/builtin/list.rs index 91cdf12..b808da2 100644 --- a/src/builtin/list.rs +++ b/src/builtin/list.rs @@ -1,6 +1,6 @@ use super::{Builtin, GlobalFunctionMap}; -use num_traits::{One, Signed, ToPrimitive, Zero}; +use num_traits::{Signed, ToPrimitive, Zero}; use crate::{ args::CallArgs, @@ -13,12 +13,10 @@ use crate::{ fn length(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(1)?; - let len = match parser.arg(&mut args, 0, "list")? { - Value::List(v, ..) => Number::from(v.len()), - Value::Map(m) => Number::from(m.len()), - _ => Number::one(), - }; - Ok(Value::Dimension(len, Unit::None)) + Ok(Value::Dimension( + Number::from(parser.arg(&mut args, 0, "list")?.as_list().len()), + Unit::None, + )) } fn nth(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 6dc41f9..4119782 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -856,14 +856,7 @@ impl<'a> Parser<'a> { self.whitespace(); let iter_val_toks = read_until_open_curly_brace(self.toks)?; let iter_val = self.parse_value_from_vec(iter_val_toks)?; - let iter = match iter_val.node.eval(iter_val.span)?.node { - Value::List(v, ..) => v, - Value::Map(m) => m - .into_iter() - .map(|(k, v)| Value::List(vec![k, v], ListSeparator::Space, Brackets::None)) - .collect(), - v => vec![v], - }; + let iter = iter_val.node.eval(iter_val.span)?.node.as_list(); self.toks.next(); self.whitespace(); let mut body = read_until_closing_curly_brace(self.toks)?; @@ -873,14 +866,7 @@ impl<'a> Parser<'a> { let mut stmts = Vec::new(); for row in iter { - let this_iterator = match row { - Value::List(v, ..) => v, - Value::Map(m) => m - .into_iter() - .map(|(k, v)| Value::List(vec![k, v], ListSeparator::Space, Brackets::None)) - .collect(), - v => vec![v], - }; + let this_iterator = row.as_list(); if vars.len() == 1 { if this_iterator.len() == 1 { diff --git a/src/value/mod.rs b/src/value/mod.rs index a8245c9..f24ed4f 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -317,6 +317,7 @@ impl Value { match self { Value::List(v, ..) => v, Value::Map(m) => m.entries(), + Value::ArgList(v) => v.into_iter().map(|val| val.node).collect(), v => vec![v], } } diff --git a/tests/arglist.rs b/tests/arglist.rs new file mode 100644 index 0000000..4636417 --- /dev/null +++ b/tests/arglist.rs @@ -0,0 +1,32 @@ +#![cfg(test)] + +#[macro_use] +mod macros; + +test!( + length_of_empty_arglist, + "@mixin foo($a...) {\n color: length($list: $a);\n}\na {\n @include foo;\n}\n", + "a {\n color: 0;\n}\n" +); +test!( + length_of_arglist_in_mixin, + "@mixin foo($a...) {\n color: length($list: $a);\n}\na {\n @include foo(a, 2, c);\n}\n", + "a {\n color: 3;\n}\n" +); +test!( + arglist_in_at_each, + "@function sum($numbers...) { + $sum: 0; + + @each $number in $numbers { + $sum: $sum + $number; + } + + @return $sum; + } + + a { + width: sum(50px, 30px, 100px); + }", + "a {\n width: 180px;\n}\n" +);