handle special functions in 3args rgba

This commit is contained in:
ConnorSkees 2020-04-06 21:58:47 -04:00
parent 97425665f9
commit b5a0957aa7

View File

@ -9,7 +9,9 @@ use crate::unit::Unit;
use crate::value::{Number, Value};
pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
let rgb = Builtin::new(|mut args, scope, super_selector| {
f.insert(
"rgb".to_owned(),
Builtin::new(|mut args, scope, super_selector| {
if args.is_empty() {
return Err("Missing argument $channels.".into());
}
@ -67,7 +69,9 @@ 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()),
};
@ -75,9 +79,13 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
} else {
let red = match arg!(args, scope, super_selector, 0, "red") {
Value::Dimension(n, Unit::None) => n,
Value::Dimension(n, Unit::Percent) => (n / Number::from(100)) * Number::from(255),
Value::Dimension(n, Unit::Percent) => {
(n / Number::from(100)) * Number::from(255)
}
v @ Value::Dimension(..) => {
return Err(format!("$red: Expected {} to have no units or \"%\".", v).into())
return Err(
format!("$red: Expected {} to have no units or \"%\".", v).into()
)
}
v if v.is_special_function() => {
let green = arg!(args, scope, super_selector, 1, "green");
@ -85,7 +93,9 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
let mut string = format!("rgb({}, {}, {}", v, green, blue);
if !args.is_empty() {
string.push_str(", ");
string.push_str(&arg!(args, scope, super_selector, 3, "alpha").to_string());
string.push_str(
&arg!(args, scope, super_selector, 3, "alpha").to_string(),
);
}
string.push(')');
return Ok(Value::Ident(string, QuoteKind::None));
@ -94,16 +104,22 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
};
let green = match arg!(args, scope, super_selector, 1, "green") {
Value::Dimension(n, Unit::None) => n,
Value::Dimension(n, Unit::Percent) => (n / Number::from(100)) * Number::from(255),
Value::Dimension(n, Unit::Percent) => {
(n / Number::from(100)) * Number::from(255)
}
v @ Value::Dimension(..) => {
return Err(format!("$green: Expected {} to have no units or \"%\".", v).into())
return Err(
format!("$green: Expected {} to have no units or \"%\".", v).into()
)
}
v if v.is_special_function() => {
let blue = arg!(args, scope, super_selector, 2, "blue");
let mut string = format!("rgb({}, {}, {}", red, v, blue);
if !args.is_empty() {
string.push_str(", ");
string.push_str(&arg!(args, scope, super_selector, 3, "alpha").to_string());
string.push_str(
&arg!(args, scope, super_selector, 3, "alpha").to_string(),
);
}
string.push(')');
return Ok(Value::Ident(string, QuoteKind::None));
@ -112,15 +128,21 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
};
let blue = match arg!(args, scope, super_selector, 2, "blue") {
Value::Dimension(n, Unit::None) => n,
Value::Dimension(n, Unit::Percent) => (n / Number::from(100)) * Number::from(255),
Value::Dimension(n, Unit::Percent) => {
(n / Number::from(100)) * Number::from(255)
}
v @ Value::Dimension(..) => {
return Err(format!("$blue: Expected {} to have no units or \"%\".", v).into())
return Err(
format!("$blue: Expected {} to have no units or \"%\".", v).into()
)
}
v if v.is_special_function() => {
let mut string = format!("rgb({}, {}, {}", red, green, v);
if !args.is_empty() {
string.push_str(", ");
string.push_str(&arg!(args, scope, super_selector, 3, "alpha").to_string());
string.push_str(
&arg!(args, scope, super_selector, 3, "alpha").to_string(),
);
}
string.push(')');
return Ok(Value::Ident(string, QuoteKind::None));
@ -137,7 +159,9 @@ 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 if v.is_special_function() => {
let string = format!("rgb({}, {}, {}, {})", red, green, blue, v);
@ -147,9 +171,172 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
};
Ok(Value::Color(Color::from_rgba(red, green, blue, alpha)))
}
});
f.insert("rgb".to_owned(), rgb.clone());
f.insert("rgba".to_owned(), rgb);
}),
);
f.insert(
"rgba".to_owned(),
Builtin::new(|mut args, scope, super_selector| {
if args.is_empty() {
return Err("Missing argument $channels.".into());
}
if args.len() == 1 {
let mut channels = match arg!(args, scope, super_selector, 0, "channels") {
Value::List(v, ..) => v,
_ => return Err("Missing argument $channels.".into()),
};
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(v) => return Err(format!("$blue: {} is not a number.", 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(v) => return Err(format!("$green: {} is not a number.", 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(v) => return Err(format!("$red: {} is not a number.", v).into()),
None => return Err("Missing element $red.".into()),
};
let color = Color::from_rgba(red, green, blue, Number::one());
Ok(Value::Color(color))
} else if args.len() == 2 {
let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c,
v => return Err(format!("$color: {} is not a color.", v).into()),
};
let alpha = match arg!(args, scope, super_selector, 1, "alpha") {
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()
)
}
v => return Err(format!("$alpha: {} is not a number.", v).into()),
};
Ok(Value::Color(color.with_alpha(alpha)))
} else {
let red = match arg!(args, scope, super_selector, 0, "red") {
Value::Dimension(n, Unit::None) => n,
Value::Dimension(n, Unit::Percent) => {
(n / Number::from(100)) * Number::from(255)
}
v @ Value::Dimension(..) => {
return Err(
format!("$red: Expected {} to have no units or \"%\".", v).into()
)
}
v if v.is_special_function() => {
let green = arg!(args, scope, super_selector, 1, "green");
let blue = arg!(args, scope, super_selector, 2, "blue");
let mut string = format!("rgba({}, {}, {}", v, green, blue);
if !args.is_empty() {
string.push_str(", ");
string.push_str(
&arg!(args, scope, super_selector, 3, "alpha").to_string(),
);
}
string.push(')');
return Ok(Value::Ident(string, QuoteKind::None));
}
v => return Err(format!("$red: {} is not a number.", v).into()),
};
let green = match arg!(args, scope, super_selector, 1, "green") {
Value::Dimension(n, Unit::None) => n,
Value::Dimension(n, Unit::Percent) => {
(n / Number::from(100)) * Number::from(255)
}
v @ Value::Dimension(..) => {
return Err(
format!("$green: Expected {} to have no units or \"%\".", v).into()
)
}
v if v.is_special_function() => {
let blue = arg!(args, scope, super_selector, 2, "blue");
let mut string = format!("rgba({}, {}, {}", red, v, blue);
if !args.is_empty() {
string.push_str(", ");
string.push_str(
&arg!(args, scope, super_selector, 3, "alpha").to_string(),
);
}
string.push(')');
return Ok(Value::Ident(string, QuoteKind::None));
}
v => return Err(format!("$green: {} is not a number.", v).into()),
};
let blue = match arg!(args, scope, super_selector, 2, "blue") {
Value::Dimension(n, Unit::None) => n,
Value::Dimension(n, Unit::Percent) => {
(n / Number::from(100)) * Number::from(255)
}
v @ Value::Dimension(..) => {
return Err(
format!("$blue: Expected {} to have no units or \"%\".", v).into()
)
}
v if v.is_special_function() => {
let mut string = format!("rgba({}, {}, {}", red, green, v);
if !args.is_empty() {
string.push_str(", ");
string.push_str(
&arg!(args, scope, super_selector, 3, "alpha").to_string(),
);
}
string.push(')');
return Ok(Value::Ident(string, QuoteKind::None));
}
v => return Err(format!("$blue: {} is not a number.", v).into()),
};
let alpha = match arg!(
args,
scope,
super_selector,
3,
"alpha" = Value::Dimension(Number::one(), 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()
)
}
v if v.is_special_function() => {
let string = format!("rgba({}, {}, {}, {})", red, green, blue, v);
return Ok(Value::Ident(string, QuoteKind::None));
}
v => return Err(format!("$alpha: {} is not a number.", v).into()),
};
Ok(Value::Color(Color::from_rgba(red, green, blue, alpha)))
}
}),
);
f.insert(
"red".to_owned(),
Builtin::new(|mut args, scope, super_selector| {