Implement 1 arg for hsl and hsla

This commit is contained in:
ConnorSkees 2020-03-19 23:44:53 -04:00
parent fb4021dae6
commit 20f702b40b
3 changed files with 183 additions and 56 deletions

View File

@ -10,6 +10,45 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
f.insert(
"hsl".to_owned(),
Box::new(|args, _| {
if args.len() == 1 {
let mut channels = match arg!(args, 0, "channels") {
Value::List(v, _) => v,
_ => return Err("Missing element $green.".into()),
};
if channels.len() > 3 {
return Err(format!(
"Only 3 elements allowed, but {} were passed.",
channels.len()
)
.into());
}
let luminance = match channels.pop() {
Some(Value::Dimension(n, _)) => n / Number::from(100),
Some(v) => return Err(format!("$luminance: {} is not a color", v).into()),
None => return Err("Missing element $luminance.".into()),
};
let saturation = match channels.pop() {
Some(Value::Dimension(n, _)) => n / Number::from(100),
Some(v) => return Err(format!("$saturation: {} is not a color", v).into()),
None => return Err("Missing element $saturation.".into()),
};
let hue = match channels.pop() {
Some(Value::Dimension(n, _)) => n,
Some(v) => return Err(format!("$hue: {} is not a color", v).into()),
None => return Err("Missing element $hue.".into()),
};
Ok(Value::Color(Color::from_hsla(
hue,
saturation,
luminance,
Number::from(1),
)))
} else {
let hue = match arg!(args, 0, "hue") {
Value::Dimension(n, _) => n,
v => return Err(format!("$hue: {} is not a number.", v).into()),
@ -30,18 +69,60 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
Value::Dimension(n, Unit::None) => n,
Value::Dimension(n, Unit::Percent) => n / Number::from(100),
v @ Value::Dimension(..) => {
return Err(format!("$alpha: Expected {} to have no units or \"%\".", v).into())
return Err(
format!("$alpha: Expected {} to have no units or \"%\".", v).into()
)
}
v => return Err(format!("$alpha: {} is not a number.", v).into()),
};
Ok(Value::Color(Color::from_hsla(
hue, saturation, luminance, alpha,
)))
}
}),
);
f.insert(
"hsla".to_owned(),
Box::new(|args, _| {
if args.len() == 1 {
let mut channels = match arg!(args, 0, "channels") {
Value::List(v, _) => v,
_ => return Err("Missing element $green.".into()),
};
if channels.len() > 3 {
return Err(format!(
"Only 3 elements allowed, but {} were passed.",
channels.len()
)
.into());
}
let luminance = match channels.pop() {
Some(Value::Dimension(n, _)) => n / Number::from(100),
Some(v) => return Err(format!("$luminance: {} is not a color", v).into()),
None => return Err("Missing element $luminance.".into()),
};
let saturation = match channels.pop() {
Some(Value::Dimension(n, _)) => n / Number::from(100),
Some(v) => return Err(format!("$saturation: {} is not a color", v).into()),
None => return Err("Missing element $saturation.".into()),
};
let hue = match channels.pop() {
Some(Value::Dimension(n, _)) => n,
Some(v) => return Err(format!("$hue: {} is not a color", v).into()),
None => return Err("Missing element $hue.".into()),
};
Ok(Value::Color(Color::from_hsla(
hue,
saturation,
luminance,
Number::from(1),
)))
} else {
let hue = match arg!(args, 0, "hue") {
Value::Dimension(n, _) => n,
v => return Err(format!("$hue: {} is not a number.", v).into()),
@ -54,17 +135,24 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
Value::Dimension(n, _) => n / Number::from(100),
v => return Err(format!("$luminance: {} is not a number.", v).into()),
};
let alpha = match arg!(args, 3, "alpha") {
let alpha = match arg!(
args,
3,
"alpha" = Value::Dimension(Number::from(1), Unit::None)
) {
Value::Dimension(n, Unit::None) => n,
Value::Dimension(n, Unit::Percent) => n / Number::from(100),
v @ Value::Dimension(..) => {
return Err(format!("$alpha: Expected {} to have no units or \"%\".", v).into())
return Err(
format!("$alpha: Expected {} to have no units or \"%\".", v).into()
)
}
v => return Err(format!("$alpha: {} is not a number.", v).into()),
};
Ok(Value::Color(Color::from_hsla(
hue, saturation, luminance, alpha,
)))
}
}),
);
f.insert(

View File

@ -15,25 +15,37 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
_ => return Err("Missing element $green.".into()),
};
assert_eq!(channels.len(), 3_usize);
if channels.len() > 3 {
return Err(format!(
"Only 3 elements allowed, but {} were passed.",
channels.len()
)
.into());
}
let blue = match channels.pop() {
Some(Value::Dimension(n, Unit::None)) => n,
Some(Value::Dimension(n, Unit::Percent)) => (n / Number::from(100)) * Number::from(255),
Some(Value::Dimension(n, Unit::Percent)) => {
(n / Number::from(100)) * Number::from(255)
}
Some(v) => return Err(format!("$blue: {} is not a color", v).into()),
None => return Err("Missing element $blue.".into()),
};
let green = match channels.pop() {
Some(Value::Dimension(n, Unit::None)) => n,
Some(Value::Dimension(n, Unit::Percent)) => (n / Number::from(100)) * Number::from(255),
Some(Value::Dimension(n, Unit::Percent)) => {
(n / Number::from(100)) * Number::from(255)
}
Some(v) => return Err(format!("$green: {} is not a color", v).into()),
None => return Err("Missing element $green.".into()),
};
let red = match channels.pop() {
Some(Value::Dimension(n, Unit::None)) => n,
Some(Value::Dimension(n, Unit::Percent)) => (n / Number::from(100)) * Number::from(255),
Some(Value::Dimension(n, Unit::Percent)) => {
(n / Number::from(100)) * Number::from(255)
}
Some(v) => return Err(format!("$red: {} is not a color", v).into()),
None => return Err("Missing element $red.".into()),
};
@ -121,25 +133,37 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
_ => return Err("Missing element $green.".into()),
};
assert_eq!(channels.len(), 3_usize);
if channels.len() > 3 {
return Err(format!(
"Only 3 elements allowed, but {} were passed.",
channels.len()
)
.into());
}
let blue = match channels.pop() {
Some(Value::Dimension(n, Unit::None)) => n,
Some(Value::Dimension(n, Unit::Percent)) => (n / Number::from(100)) * Number::from(255),
Some(Value::Dimension(n, Unit::Percent)) => {
(n / Number::from(100)) * Number::from(255)
}
Some(v) => return Err(format!("$blue: {} is not a color", v).into()),
None => return Err("Missing element $blue.".into()),
};
let green = match channels.pop() {
Some(Value::Dimension(n, Unit::None)) => n,
Some(Value::Dimension(n, Unit::Percent)) => (n / Number::from(100)) * Number::from(255),
Some(Value::Dimension(n, Unit::Percent)) => {
(n / Number::from(100)) * Number::from(255)
}
Some(v) => return Err(format!("$green: {} is not a color", v).into()),
None => return Err("Missing element $green.".into()),
};
let red = match channels.pop() {
Some(Value::Dimension(n, Unit::None)) => n,
Some(Value::Dimension(n, Unit::Percent)) => (n / Number::from(100)) * Number::from(255),
Some(Value::Dimension(n, Unit::Percent)) => {
(n / Number::from(100)) * Number::from(255)
}
Some(v) => return Err(format!("$red: {} is not a color", v).into()),
None => return Err("Missing element $red.".into()),
};

View File

@ -501,3 +501,18 @@ test!(
// "a {\n color: ie_hex-str(rgba(0, 255, 0, 0.5));\n}\n",
// "a {\n color: #8000FF00;\n}\n"
// );
test!(
rgba_1_arg,
"a {\n color: rgba(74.7% 173 93%);\n}\n",
"a {\n color: #beaded;\n}\n"
);
test!(
hsla_1_arg,
"a {\n color: hsla(60 60% 50%);\n}\n",
"a {\n color: #cccc33;\n}\n"
);
test!(
hsla_1_arg_weird_units,
"a {\n color: hsla(60foo 60foo 50foo);\n}\n",
"a {\n color: #cccc33;\n}\n"
);