From 24176bb1f0fe5acd266a1ebed7b6a2983b6f8c34 Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Fri, 3 Apr 2020 15:54:59 -0400 Subject: [PATCH] initial implementation of zip --- src/builtin/list.rs | 35 ++++++++++++++++++++++++++++++++++- tests/list.rs | 5 +++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/builtin/list.rs b/src/builtin/list.rs index 4d5e377..ef172aa 100644 --- a/src/builtin/list.rs +++ b/src/builtin/list.rs @@ -228,7 +228,7 @@ pub(crate) fn register(f: &mut HashMap) { // TODO: find a way around this unwrap. // It should be impossible to hit as the arg is // evaluated prior to checking equality, but - // it is still dirty. + // it is still dirty. // Potential input to fuzz: index(1px 1in 1cm, 96px + 1rem) let index = match list .into_iter() @@ -240,4 +240,37 @@ pub(crate) fn register(f: &mut HashMap) { Ok(Value::Dimension(index, Unit::None)) }), ); + f.insert( + "zip".to_owned(), + Box::new(|mut args, _| { + let lists = args + .get_variadic()? + .into_iter() + .map(|x| match x { + Value::List(v, ..) => v, + Value::Map(m) => m.entries(), + v => vec![v], + }) + .collect::>>(); + + let len = lists.iter().map(|l| l.len()).min().unwrap_or(0); + + if len == 0 { + return Ok(Value::List( + Vec::new(), + ListSeparator::Comma, + Brackets::None, + )); + } + + let result = (0..len) + .map(|i| { + let items = lists.iter().map(|v| v[i].clone()).collect(); + Value::List(items, ListSeparator::Space, Brackets::None) + }) + .collect(); + + Ok(Value::List(result, ListSeparator::Comma, Brackets::None)) + }), + ); } diff --git a/tests/list.rs b/tests/list.rs index 303aca1..063b43f 100644 --- a/tests/list.rs +++ b/tests/list.rs @@ -298,3 +298,8 @@ test!( "a {\n color: index(1px 1in 1cm, 96px);\n}\n", "a {\n color: 2;\n}\n" ); +test!( + zip_three, + "a {\n color: zip(1px 1px 3px, solid dashed solid, red green blue);\n}\n", + "a {\n color: 1px solid red, 1px dashed green, 3px solid blue;\n}\n" +);