diff --git a/src/builtin/color/rgb.rs b/src/builtin/color/rgb.rs index cc0bd1a..0afc2f8 100644 --- a/src/builtin/color/rgb.rs +++ b/src/builtin/color/rgb.rs @@ -7,8 +7,48 @@ use crate::value::{Number, Value}; pub(crate) fn register(f: &mut BTreeMap) { decl!(f "rgb", |args, _| { - let channels = args.get("channels").unwrap_or(&Value::Null); - if channels.is_null() { + if args.len() == 1 { + let mut channels = match arg!(args, 0, "channels").eval() { + Value::List(v, _) => v, + _ => todo!("missing element $green") + }; + + assert_eq!(channels.len(), 3_usize); + + let blue = match channels.pop() { + Some(Value::Dimension(n, Unit::None)) => n, + Some(Value::Dimension(n, Unit::Percent)) => n / Number::from(100), + _ => todo!("$blue: ___ is not a color") + }; + + let green = match channels.pop() { + Some(Value::Dimension(n, Unit::None)) => n, + Some(Value::Dimension(n, Unit::Percent)) => n / Number::from(100), + _ => todo!("$green: ___ is not a color") + }; + + let red = match channels.pop() { + Some(Value::Dimension(n, Unit::None)) => n, + Some(Value::Dimension(n, Unit::Percent)) => n / Number::from(100), + _ => todo!("$red: ___ is not a color") + }; + + let color = Color::from_rgba(red, green, blue, Number::from(1)); + + Some(Value::Color(color)) + + } else if args.len() == 2 { + let color = match arg!(args, 0, "color").eval() { + Value::Color(c) => c, + _ => todo!("expected color") + }; + let alpha = match arg!(args, 1, "alpha").eval() { + Value::Dimension(n, Unit::None) => n, + Value::Dimension(n, Unit::Percent) => n / Number::from(100), + _ => todo!("expected either unitless or % number for alpha"), + }; + Some(Value::Color(color.with_alpha(alpha))) + } else { let red = match arg!(args, 0, "red").eval() { Value::Dimension(n, Unit::None) => n, Value::Dimension(n, Unit::Percent) => (n / Number::from(100)) * Number::from(255), @@ -24,18 +64,15 @@ pub(crate) fn register(f: &mut BTreeMap) { Value::Dimension(n, Unit::Percent) => (n / Number::from(100)) * Number::from(255), _ => todo!("expected either unitless or % number for alpha"), }; - let alpha = match arg!(args, 3, "alpha"=Value::Dimension(Number::from(1), Unit::None)) { + let alpha = match arg!(args, 3, "alpha"=Value::Dimension(Number::from(1), Unit::None)).eval() { Value::Dimension(n, Unit::None) => n, Value::Dimension(n, Unit::Percent) => n / Number::from(100), - _ => todo!("non-number alpha given to builtin function `rgb()`") + _ => todo!("expected either unitless or % number for alpha") }; Some(Value::Color(Color::from_rgba(red, green, blue, alpha))) - } else { - todo!("channels variable in `rgb`") } }); decl!(f "rgba", |args, _| { - if args.len() == 1 { let mut channels = match arg!(args, 0, "channels").eval() { Value::List(v, _) => v, diff --git a/tests/color.rs b/tests/color.rs index 786607e..2c9a93b 100644 --- a/tests/color.rs +++ b/tests/color.rs @@ -88,6 +88,11 @@ test!( // "a {\n color: rgba(1 2 3);;\n}\n", // "a {\n color: #010203;\n}\n" // ); +test!( + rgb_two_args, + "a {\n color: rgb(#123, 0);\n}\n", + "a {\n color: rgba(17, 34, 51, 0);\n}\n" +); test!( rgba_two_args, "a {\n color: rgba(red, 0.5);\n}\n",