refactor parsing of special hsl/rgb fns
This commit is contained in:
parent
c6cb7c1d68
commit
1e2e32140b
@ -18,7 +18,9 @@ fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
return Err(("Missing argument $channels.", args.span()).into());
|
return Err(("Missing argument $channels.", args.span()).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if args.len() == 1 {
|
let len = args.len();
|
||||||
|
|
||||||
|
if len == 1 {
|
||||||
let mut channels = match args.get_err(0, "channels")? {
|
let mut channels = match args.get_err(0, "channels")? {
|
||||||
Value::List(v, ..) => v,
|
Value::List(v, ..) => v,
|
||||||
_ => return Err(("Missing argument $channels.", args.span()).into()),
|
_ => return Err(("Missing argument $channels.", args.span()).into()),
|
||||||
@ -99,30 +101,42 @@ fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
Number::one(),
|
Number::one(),
|
||||||
))))
|
))))
|
||||||
} else {
|
} else {
|
||||||
let hue = match args.get_err(0, "hue")? {
|
let hue = args.get_err(0, "hue")?;
|
||||||
Value::Dimension(Some(n), ..) => n,
|
|
||||||
Value::Dimension(None, ..) => todo!(),
|
|
||||||
v if v.is_special_function() => {
|
|
||||||
let saturation = args.get_err(1, "saturation")?;
|
let saturation = args.get_err(1, "saturation")?;
|
||||||
let lightness = args.get_err(2, "lightness")?;
|
let lightness = args.get_err(2, "lightness")?;
|
||||||
let mut string = format!(
|
let alpha = args.default_arg(
|
||||||
"{}({}, {}, {}",
|
3,
|
||||||
|
"alpha",
|
||||||
|
Value::Dimension(Some(Number::one()), Unit::None, true),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
if [&hue, &saturation, &lightness, &alpha]
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.any(Value::is_special_function)
|
||||||
|
{
|
||||||
|
return Ok(Value::String(
|
||||||
|
format!(
|
||||||
|
"{}({})",
|
||||||
name,
|
name,
|
||||||
v.to_css_string(args.span(), parser.options.is_compressed())?,
|
Value::List(
|
||||||
saturation.to_css_string(args.span(), parser.options.is_compressed())?,
|
if len == 4 {
|
||||||
lightness.to_css_string(args.span(), parser.options.is_compressed())?
|
vec![hue, saturation, lightness, alpha]
|
||||||
);
|
} else {
|
||||||
if !args.is_empty() {
|
vec![hue, saturation, lightness]
|
||||||
string.push_str(", ");
|
},
|
||||||
string.push_str(
|
ListSeparator::Comma,
|
||||||
&args
|
Brackets::None
|
||||||
.get_err(3, "alpha")?
|
)
|
||||||
.to_css_string(args.span(), parser.options.is_compressed())?,
|
.to_css_string(args.span(), false)?
|
||||||
);
|
),
|
||||||
}
|
QuoteKind::None,
|
||||||
string.push(')');
|
));
|
||||||
return Ok(Value::String(string, QuoteKind::None));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let hue = match hue {
|
||||||
|
Value::Dimension(Some(n), ..) => n,
|
||||||
|
Value::Dimension(None, ..) => todo!(),
|
||||||
v => {
|
v => {
|
||||||
return Err((
|
return Err((
|
||||||
format!("$hue: {} is not a number.", v.inspect(args.span())?),
|
format!("$hue: {} is not a number.", v.inspect(args.span())?),
|
||||||
@ -131,29 +145,9 @@ fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let saturation = match args.get_err(1, "saturation")? {
|
let saturation = match saturation {
|
||||||
Value::Dimension(Some(n), ..) => n / Number::from(100),
|
Value::Dimension(Some(n), ..) => n / Number::from(100),
|
||||||
Value::Dimension(None, ..) => todo!(),
|
Value::Dimension(None, ..) => todo!(),
|
||||||
v if v.is_special_function() => {
|
|
||||||
let lightness = args.get_err(2, "lightness")?;
|
|
||||||
let mut string = format!(
|
|
||||||
"{}({}, {}, {}",
|
|
||||||
name,
|
|
||||||
hue.to_string(parser.options.is_compressed()),
|
|
||||||
v.to_css_string(args.span(), parser.options.is_compressed())?,
|
|
||||||
lightness.to_css_string(args.span(), parser.options.is_compressed())?
|
|
||||||
);
|
|
||||||
if !args.is_empty() {
|
|
||||||
string.push_str(", ");
|
|
||||||
string.push_str(
|
|
||||||
&args
|
|
||||||
.get_err(3, "alpha")?
|
|
||||||
.to_css_string(args.span(), parser.options.is_compressed())?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
string.push(')');
|
|
||||||
return Ok(Value::String(string, QuoteKind::None));
|
|
||||||
}
|
|
||||||
v => {
|
v => {
|
||||||
return Err((
|
return Err((
|
||||||
format!(
|
format!(
|
||||||
@ -165,28 +159,9 @@ fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let lightness = match args.get_err(2, "lightness")? {
|
let lightness = match lightness {
|
||||||
Value::Dimension(Some(n), ..) => n / Number::from(100),
|
Value::Dimension(Some(n), ..) => n / Number::from(100),
|
||||||
Value::Dimension(None, ..) => todo!(),
|
Value::Dimension(None, ..) => todo!(),
|
||||||
v if v.is_special_function() => {
|
|
||||||
let mut string = format!(
|
|
||||||
"{}({}, {}, {}",
|
|
||||||
name,
|
|
||||||
hue.to_string(parser.options.is_compressed()),
|
|
||||||
saturation.to_string(parser.options.is_compressed()),
|
|
||||||
v.to_css_string(args.span(), parser.options.is_compressed())?
|
|
||||||
);
|
|
||||||
if !args.is_empty() {
|
|
||||||
string.push_str(", ");
|
|
||||||
string.push_str(
|
|
||||||
&args
|
|
||||||
.get_err(3, "alpha")?
|
|
||||||
.to_css_string(args.span(), parser.options.is_compressed())?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
string.push(')');
|
|
||||||
return Ok(Value::String(string, QuoteKind::None));
|
|
||||||
}
|
|
||||||
v => {
|
v => {
|
||||||
return Err((
|
return Err((
|
||||||
format!(
|
format!(
|
||||||
@ -198,11 +173,7 @@ fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let alpha = match args.default_arg(
|
let alpha = match alpha {
|
||||||
3,
|
|
||||||
"alpha",
|
|
||||||
Value::Dimension(Some(Number::one()), Unit::None, true),
|
|
||||||
)? {
|
|
||||||
Value::Dimension(Some(n), Unit::None, _) => n,
|
Value::Dimension(Some(n), Unit::None, _) => n,
|
||||||
Value::Dimension(Some(n), Unit::Percent, _) => n / Number::from(100),
|
Value::Dimension(Some(n), Unit::Percent, _) => n / Number::from(100),
|
||||||
Value::Dimension(None, ..) => todo!(),
|
Value::Dimension(None, ..) => todo!(),
|
||||||
@ -216,19 +187,6 @@ fn inner_hsl(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
)
|
)
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
v if v.is_special_function() => {
|
|
||||||
return Ok(Value::String(
|
|
||||||
format!(
|
|
||||||
"{}({}, {}, {}, {})",
|
|
||||||
name,
|
|
||||||
hue.to_string(parser.options.is_compressed()),
|
|
||||||
saturation.to_string(parser.options.is_compressed()),
|
|
||||||
lightness.to_string(parser.options.is_compressed()),
|
|
||||||
v.to_css_string(args.span(), parser.options.is_compressed())?
|
|
||||||
),
|
|
||||||
QuoteKind::None,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
v => {
|
v => {
|
||||||
return Err((
|
return Err((
|
||||||
format!("$alpha: {} is not a number.", v.inspect(args.span())?),
|
format!("$alpha: {} is not a number.", v.inspect(args.span())?),
|
||||||
|
@ -20,7 +20,9 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
return Err(("Missing argument $channels.", args.span()).into());
|
return Err(("Missing argument $channels.", args.span()).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if args.len() == 1 {
|
let len = args.len();
|
||||||
|
|
||||||
|
if len == 1 {
|
||||||
let mut channels = match args.get_err(0, "channels")? {
|
let mut channels = match args.get_err(0, "channels")? {
|
||||||
Value::List(v, ..) => v,
|
Value::List(v, ..) => v,
|
||||||
_ => return Err(("Missing argument $channels.", args.span()).into()),
|
_ => return Err(("Missing argument $channels.", args.span()).into()),
|
||||||
@ -150,7 +152,7 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
let color = Color::from_rgba(red, green, blue, Number::one());
|
let color = Color::from_rgba(red, green, blue, Number::one());
|
||||||
|
|
||||||
Ok(Value::Color(Box::new(color)))
|
Ok(Value::Color(Box::new(color)))
|
||||||
} else if args.len() == 2 {
|
} else if len == 2 {
|
||||||
let color = match args.get_err(0, "color")? {
|
let color = match args.get_err(0, "color")? {
|
||||||
Value::Color(c) => c,
|
Value::Color(c) => c,
|
||||||
v if v.is_special_function() => {
|
v if v.is_special_function() => {
|
||||||
@ -210,7 +212,40 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
};
|
};
|
||||||
Ok(Value::Color(Box::new(color.with_alpha(alpha))))
|
Ok(Value::Color(Box::new(color.with_alpha(alpha))))
|
||||||
} else {
|
} else {
|
||||||
let red = match args.get_err(0, "red")? {
|
let red = args.get_err(0, "red")?;
|
||||||
|
let green = args.get_err(1, "green")?;
|
||||||
|
let blue = args.get_err(2, "blue")?;
|
||||||
|
let alpha = args.default_arg(
|
||||||
|
3,
|
||||||
|
"alpha",
|
||||||
|
Value::Dimension(Some(Number::one()), Unit::None, true),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
if [&red, &green, &blue, &alpha]
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.any(Value::is_special_function)
|
||||||
|
{
|
||||||
|
return Ok(Value::String(
|
||||||
|
format!(
|
||||||
|
"{}({})",
|
||||||
|
name,
|
||||||
|
Value::List(
|
||||||
|
if len == 4 {
|
||||||
|
vec![red, green, blue, alpha]
|
||||||
|
} else {
|
||||||
|
vec![red, green, blue]
|
||||||
|
},
|
||||||
|
ListSeparator::Comma,
|
||||||
|
Brackets::None
|
||||||
|
)
|
||||||
|
.to_css_string(args.span(), false)?
|
||||||
|
),
|
||||||
|
QuoteKind::None,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let red = match red {
|
||||||
Value::Dimension(Some(n), Unit::None, _) => n,
|
Value::Dimension(Some(n), Unit::None, _) => n,
|
||||||
Value::Dimension(Some(n), Unit::Percent, _) => {
|
Value::Dimension(Some(n), Unit::Percent, _) => {
|
||||||
(n / Number::from(100)) * Number::from(255)
|
(n / Number::from(100)) * Number::from(255)
|
||||||
@ -226,27 +261,6 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
)
|
)
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
v if v.is_special_function() => {
|
|
||||||
let green = args.get_err(1, "green")?;
|
|
||||||
let blue = args.get_err(2, "blue")?;
|
|
||||||
let mut string = format!(
|
|
||||||
"{}({}, {}, {}",
|
|
||||||
name,
|
|
||||||
v.to_css_string(args.span(), parser.options.is_compressed())?,
|
|
||||||
green.to_css_string(args.span(), parser.options.is_compressed())?,
|
|
||||||
blue.to_css_string(args.span(), parser.options.is_compressed())?
|
|
||||||
);
|
|
||||||
if !args.is_empty() {
|
|
||||||
string.push_str(", ");
|
|
||||||
string.push_str(
|
|
||||||
&args
|
|
||||||
.get_err(3, "alpha")?
|
|
||||||
.to_css_string(args.span(), parser.options.is_compressed())?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
string.push(')');
|
|
||||||
return Ok(Value::String(string, QuoteKind::None));
|
|
||||||
}
|
|
||||||
v => {
|
v => {
|
||||||
return Err((
|
return Err((
|
||||||
format!("$red: {} is not a number.", v.inspect(args.span())?),
|
format!("$red: {} is not a number.", v.inspect(args.span())?),
|
||||||
@ -255,7 +269,7 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let green = match args.get_err(1, "green")? {
|
let green = match green {
|
||||||
Value::Dimension(Some(n), Unit::None, _) => n,
|
Value::Dimension(Some(n), Unit::None, _) => n,
|
||||||
Value::Dimension(Some(n), Unit::Percent, _) => {
|
Value::Dimension(Some(n), Unit::Percent, _) => {
|
||||||
(n / Number::from(100)) * Number::from(255)
|
(n / Number::from(100)) * Number::from(255)
|
||||||
@ -271,26 +285,6 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
)
|
)
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
v if v.is_special_function() => {
|
|
||||||
let blue = args.get_err(2, "blue")?;
|
|
||||||
let mut string = format!(
|
|
||||||
"{}({}, {}, {}",
|
|
||||||
name,
|
|
||||||
red.to_string(parser.options.is_compressed()),
|
|
||||||
v.to_css_string(args.span(), parser.options.is_compressed())?,
|
|
||||||
blue.to_css_string(args.span(), parser.options.is_compressed())?
|
|
||||||
);
|
|
||||||
if !args.is_empty() {
|
|
||||||
string.push_str(", ");
|
|
||||||
string.push_str(
|
|
||||||
&args
|
|
||||||
.get_err(3, "alpha")?
|
|
||||||
.to_css_string(args.span(), parser.options.is_compressed())?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
string.push(')');
|
|
||||||
return Ok(Value::String(string, QuoteKind::None));
|
|
||||||
}
|
|
||||||
v => {
|
v => {
|
||||||
return Err((
|
return Err((
|
||||||
format!("$green: {} is not a number.", v.inspect(args.span())?),
|
format!("$green: {} is not a number.", v.inspect(args.span())?),
|
||||||
@ -299,7 +293,7 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let blue = match args.get_err(2, "blue")? {
|
let blue = match blue {
|
||||||
Value::Dimension(Some(n), Unit::None, _) => n,
|
Value::Dimension(Some(n), Unit::None, _) => n,
|
||||||
Value::Dimension(Some(n), Unit::Percent, _) => {
|
Value::Dimension(Some(n), Unit::Percent, _) => {
|
||||||
(n / Number::from(100)) * Number::from(255)
|
(n / Number::from(100)) * Number::from(255)
|
||||||
@ -315,25 +309,6 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
)
|
)
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
v if v.is_special_function() => {
|
|
||||||
let mut string = format!(
|
|
||||||
"{}({}, {}, {}",
|
|
||||||
name,
|
|
||||||
red.to_string(parser.options.is_compressed()),
|
|
||||||
green.to_string(parser.options.is_compressed()),
|
|
||||||
v.to_css_string(args.span(), parser.options.is_compressed())?
|
|
||||||
);
|
|
||||||
if !args.is_empty() {
|
|
||||||
string.push_str(", ");
|
|
||||||
string.push_str(
|
|
||||||
&args
|
|
||||||
.get_err(3, "alpha")?
|
|
||||||
.to_css_string(args.span(), parser.options.is_compressed())?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
string.push(')');
|
|
||||||
return Ok(Value::String(string, QuoteKind::None));
|
|
||||||
}
|
|
||||||
v => {
|
v => {
|
||||||
return Err((
|
return Err((
|
||||||
format!("$blue: {} is not a number.", v.inspect(args.span())?),
|
format!("$blue: {} is not a number.", v.inspect(args.span())?),
|
||||||
@ -342,11 +317,7 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let alpha = match args.default_arg(
|
let alpha = match alpha {
|
||||||
3,
|
|
||||||
"alpha",
|
|
||||||
Value::Dimension(Some(Number::one()), Unit::None, true),
|
|
||||||
)? {
|
|
||||||
Value::Dimension(Some(n), Unit::None, _) => n,
|
Value::Dimension(Some(n), Unit::None, _) => n,
|
||||||
Value::Dimension(Some(n), Unit::Percent, _) => n / Number::from(100),
|
Value::Dimension(Some(n), Unit::Percent, _) => n / Number::from(100),
|
||||||
Value::Dimension(None, ..) => todo!(),
|
Value::Dimension(None, ..) => todo!(),
|
||||||
@ -360,17 +331,6 @@ fn inner_rgb(name: &'static str, mut args: CallArgs, parser: &mut Parser) -> Sas
|
|||||||
)
|
)
|
||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
v if v.is_special_function() => {
|
|
||||||
let string = format!(
|
|
||||||
"{}({}, {}, {}, {})",
|
|
||||||
name,
|
|
||||||
red.to_string(parser.options.is_compressed()),
|
|
||||||
green.to_string(parser.options.is_compressed()),
|
|
||||||
blue.to_string(parser.options.is_compressed()),
|
|
||||||
v.to_css_string(args.span(), parser.options.is_compressed())?
|
|
||||||
);
|
|
||||||
return Ok(Value::String(string, QuoteKind::None));
|
|
||||||
}
|
|
||||||
v => {
|
v => {
|
||||||
return Err((
|
return Err((
|
||||||
format!("$alpha: {} is not a number.", v.inspect(args.span())?),
|
format!("$alpha: {} is not a number.", v.inspect(args.span())?),
|
||||||
|
@ -737,6 +737,26 @@ test!(
|
|||||||
"a {\n color: rgba(1 2 max(3, 3));\n}\n",
|
"a {\n color: rgba(1 2 max(3, 3));\n}\n",
|
||||||
"a {\n color: rgba(1, 2, max(3, 3));\n}\n"
|
"a {\n color: rgba(1, 2, max(3, 3));\n}\n"
|
||||||
);
|
);
|
||||||
|
test!(
|
||||||
|
rgb_special_fn_4_arg_maintains_units,
|
||||||
|
"a {\n color: rgb(1, 0.02, 3%, max(0.4));\n}\n",
|
||||||
|
"a {\n color: rgb(1, 0.02, 3%, max(0.4));\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
rgb_special_fn_3_arg_maintains_units,
|
||||||
|
"a {\n color: rgb(1, 0.02, max(0.4));\n}\n",
|
||||||
|
"a {\n color: rgb(1, 0.02, max(0.4));\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
hsl_special_fn_4_arg_maintains_units,
|
||||||
|
"a {\n color: hsl(1, 0.02, 3%, max(0.4));\n}\n",
|
||||||
|
"a {\n color: hsl(1, 0.02, 3%, max(0.4));\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
hsl_special_fn_3_arg_maintains_units,
|
||||||
|
"a {\n color: hsl(1, 0.02, max(0.4));\n}\n",
|
||||||
|
"a {\n color: hsl(1, 0.02, max(0.4));\n}\n"
|
||||||
|
);
|
||||||
test!(
|
test!(
|
||||||
#[ignore = "we do not check if interpolation occurred"]
|
#[ignore = "we do not check if interpolation occurred"]
|
||||||
interpolated_named_color_is_not_color,
|
interpolated_named_color_is_not_color,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user