Skip to content

Commit a2013cd

Browse files
committed
Use Option<f32> for hsl components as well.
1 parent c1d4607 commit a2013cd

File tree

2 files changed

+76
-152
lines changed

2 files changed

+76
-152
lines changed

src/color.rs

+39-24
Original file line numberDiff line numberDiff line change
@@ -205,17 +205,22 @@ impl ToCss for RGBA {
205205
#[derive(Clone, Copy, PartialEq, Debug)]
206206
pub struct Hsl {
207207
/// The hue component.
208-
pub hue: f32,
208+
pub hue: Option<f32>,
209209
/// The saturation component.
210-
pub saturation: f32,
210+
pub saturation: Option<f32>,
211211
/// The lightness component.
212-
pub lightness: f32,
212+
pub lightness: Option<f32>,
213213
/// The alpha component.
214-
pub alpha: f32,
214+
pub alpha: Option<f32>,
215215
}
216216

217217
impl Hsl {
218-
pub fn new(hue: f32, saturation: f32, lightness: f32, alpha: f32) -> Self {
218+
pub fn new(
219+
hue: Option<f32>,
220+
saturation: Option<f32>,
221+
lightness: Option<f32>,
222+
alpha: Option<f32>,
223+
) -> Self {
219224
Self {
220225
hue,
221226
saturation,
@@ -231,9 +236,13 @@ impl ToCss for Hsl {
231236
W: fmt::Write,
232237
{
233238
// HSL serializes to RGB, so we have to convert it.
234-
let (red, green, blue) = hsl_to_rgb(self.hue / 360.0, self.saturation, self.lightness);
239+
let (red, green, blue) = hsl_to_rgb(
240+
self.hue.unwrap_or(0.0) / 360.0,
241+
self.saturation.unwrap_or(0.0),
242+
self.lightness.unwrap_or(0.0),
243+
);
235244

236-
RGBA::from_floats(red, green, blue, self.alpha).to_css(dest)
245+
RGBA::from_floats(red, green, blue, self.alpha.unwrap_or(0.0)).to_css(dest)
237246
}
238247
}
239248

@@ -830,7 +839,12 @@ pub trait FromParsedColor {
830839
fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self;
831840

832841
/// Construct a new color from hue, saturation, lightness and alpha components.
833-
fn from_hsl(hue: f32, saturation: f32, lightness: f32, alpha: f32) -> Self;
842+
fn from_hsl(
843+
hue: Option<f32>,
844+
saturation: Option<f32>,
845+
lightness: Option<f32>,
846+
alpha: Option<f32>,
847+
) -> Self;
834848

835849
/// Construct a new color from hue, blackness, whiteness and alpha components.
836850
fn from_hwb(
@@ -915,7 +929,12 @@ impl FromParsedColor for Color {
915929
Color::Rgba(RGBA::new(red, green, blue, alpha))
916930
}
917931

918-
fn from_hsl(hue: f32, saturation: f32, lightness: f32, alpha: f32) -> Self {
932+
fn from_hsl(
933+
hue: Option<f32>,
934+
saturation: Option<f32>,
935+
lightness: Option<f32>,
936+
alpha: Option<f32>,
937+
) -> Self {
919938
Color::Hsl(Hsl::new(hue, saturation, lightness, alpha))
920939
}
921940

@@ -1362,28 +1381,24 @@ where
13621381
// the legacy syntax.
13631382
let is_legacy_syntax = maybe_hue.is_some() && arguments.try_parse(|p| p.expect_comma()).is_ok();
13641383

1365-
let saturation: f32;
1366-
let lightness: f32;
1384+
let saturation: Option<f32>;
1385+
let lightness: Option<f32>;
13671386

13681387
let alpha = if is_legacy_syntax {
1369-
saturation = color_parser.parse_percentage(arguments)?;
1388+
saturation = Some(color_parser.parse_percentage(arguments)?);
13701389
arguments.expect_comma()?;
1371-
lightness = color_parser.parse_percentage(arguments)?;
1372-
parse_legacy_alpha(color_parser, arguments)?
1390+
lightness = Some(color_parser.parse_percentage(arguments)?);
1391+
Some(parse_legacy_alpha(color_parser, arguments)?)
13731392
} else {
1374-
saturation = parse_none_or(arguments, |p| color_parser.parse_percentage(p))?.unwrap_or(0.0);
1375-
lightness = parse_none_or(arguments, |p| color_parser.parse_percentage(p))?.unwrap_or(0.0);
1393+
saturation = parse_none_or(arguments, |p| color_parser.parse_percentage(p))?;
1394+
lightness = parse_none_or(arguments, |p| color_parser.parse_percentage(p))?;
13761395

1377-
parse_modern_alpha(color_parser, arguments)?.unwrap_or(0.0)
1396+
parse_modern_alpha(color_parser, arguments)?
13781397
};
13791398

1380-
let hue = if let Some(h) = maybe_hue {
1381-
normalize_hue(h.degrees())
1382-
} else {
1383-
0.0
1384-
};
1385-
let saturation = saturation.clamp(0.0, 1.0);
1386-
let lightness = lightness.clamp(0.0, 1.0);
1399+
let hue = maybe_hue.map(|h| normalize_hue(h.degrees()));
1400+
let saturation = saturation.map(|s| s.clamp(0.0, 1.0));
1401+
let lightness = lightness.map(|l| l.clamp(0.0, 1.0));
13871402

13881403
Ok(P::Output::from_hsl(hue, saturation, lightness, alpha))
13891404
}

src/tests.rs

+37-128
Original file line numberDiff line numberDiff line change
@@ -1519,7 +1519,7 @@ fn generic_parser() {
15191519
enum OutputType {
15201520
CurrentColor,
15211521
Rgba(u8, u8, u8, f32),
1522-
Hsl(f32, f32, f32, f32),
1522+
Hsl(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
15231523
Hwb(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
15241524
Lab(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
15251525
Lch(Option<f32>, Option<f32>, Option<f32>, Option<f32>),
@@ -1543,7 +1543,12 @@ fn generic_parser() {
15431543
OutputType::Rgba(red, green, blue, alpha)
15441544
}
15451545

1546-
fn from_hsl(hue: f32, saturation: f32, lightness: f32, alpha: f32) -> Self {
1546+
fn from_hsl(
1547+
hue: Option<f32>,
1548+
saturation: Option<f32>,
1549+
lightness: Option<f32>,
1550+
alpha: Option<f32>,
1551+
) -> Self {
15471552
OutputType::Hsl(hue, saturation, lightness, alpha)
15481553
}
15491554

@@ -1609,133 +1614,37 @@ fn generic_parser() {
16091614
type Error = ();
16101615
}
16111616

1617+
#[rustfmt::skip]
16121618
const TESTS: &[(&str, OutputType)] = &[
1613-
("currentColor", OutputType::CurrentColor),
1614-
("rgb(1, 2, 3)", OutputType::Rgba(1, 2, 3, 1.0)),
1615-
("rgba(1, 2, 3, 0.4)", OutputType::Rgba(1, 2, 3, 0.4)),
1616-
("rgb(none none none / none)", OutputType::Rgba(0, 0, 0, 0.0)),
1617-
("rgb(1 none 3 / none)", OutputType::Rgba(1, 0, 3, 0.0)),
1618-
(
1619-
"hsla(45deg, 20%, 30%, 0.4)",
1620-
OutputType::Hsl(45.0, 0.2, 0.3, 0.4),
1621-
),
1622-
("hsl(45deg none none)", OutputType::Hsl(45.0, 0.0, 0.0, 1.0)),
1623-
(
1624-
"hsl(none 10% none / none)",
1625-
OutputType::Hsl(0.0, 0.1, 0.0, 0.0),
1626-
),
1627-
(
1628-
"hsl(120 100.0% 50.0%)",
1629-
OutputType::Hsl(120.0, 1.0, 0.5, 1.0),
1630-
),
1631-
(
1632-
"hwb(45deg 20% 30% / 0.4)",
1633-
OutputType::Hwb(Some(45.0), Some(0.2), Some(0.3), Some(0.4)),
1634-
),
1635-
(
1636-
"lab(100 20 30 / 0.4)",
1637-
OutputType::Lab(Some(100.0), Some(20.0), Some(30.0), Some(0.4)),
1638-
),
1639-
(
1640-
"lch(100 20 30 / 0.4)",
1641-
OutputType::Lch(Some(100.0), Some(20.0), Some(30.0), Some(0.4)),
1642-
),
1643-
(
1644-
"oklab(100 20 30 / 0.4)",
1645-
OutputType::Oklab(Some(100.0), Some(20.0), Some(30.0), Some(0.4)),
1646-
),
1647-
(
1648-
"oklch(100 20 30 / 0.4)",
1649-
OutputType::Oklch(Some(100.0), Some(20.0), Some(30.0), Some(0.4)),
1650-
),
1651-
(
1652-
"color(srgb 0.1 0.2 0.3 / 0.4)",
1653-
OutputType::ColorFunction(
1654-
PredefinedColorSpace::Srgb,
1655-
Some(0.1),
1656-
Some(0.2),
1657-
Some(0.3),
1658-
Some(0.4),
1659-
),
1660-
),
1661-
(
1662-
"color(srgb-linear 0.1 0.2 0.3 / 0.4)",
1663-
OutputType::ColorFunction(
1664-
PredefinedColorSpace::SrgbLinear,
1665-
Some(0.1),
1666-
Some(0.2),
1667-
Some(0.3),
1668-
Some(0.4),
1669-
),
1670-
),
1671-
(
1672-
"color(display-p3 0.1 0.2 0.3 / 0.4)",
1673-
OutputType::ColorFunction(
1674-
PredefinedColorSpace::DisplayP3,
1675-
Some(0.1),
1676-
Some(0.2),
1677-
Some(0.3),
1678-
Some(0.4),
1679-
),
1680-
),
1681-
(
1682-
"color(a98-rgb 0.1 0.2 0.3 / 0.4)",
1683-
OutputType::ColorFunction(
1684-
PredefinedColorSpace::A98Rgb,
1685-
Some(0.1),
1686-
Some(0.2),
1687-
Some(0.3),
1688-
Some(0.4),
1689-
),
1690-
),
1691-
(
1692-
"color(prophoto-rgb 0.1 0.2 0.3 / 0.4)",
1693-
OutputType::ColorFunction(
1694-
PredefinedColorSpace::ProphotoRgb,
1695-
Some(0.1),
1696-
Some(0.2),
1697-
Some(0.3),
1698-
Some(0.4),
1699-
),
1700-
),
1701-
(
1702-
"color(rec2020 0.1 0.2 0.3 / 0.4)",
1703-
OutputType::ColorFunction(
1704-
PredefinedColorSpace::Rec2020,
1705-
Some(0.1),
1706-
Some(0.2),
1707-
Some(0.3),
1708-
Some(0.4),
1709-
),
1710-
),
1711-
(
1712-
"color(xyz-d50 0.1 0.2 0.3 / 0.4)",
1713-
OutputType::ColorFunction(
1714-
PredefinedColorSpace::XyzD50,
1715-
Some(0.1),
1716-
Some(0.2),
1717-
Some(0.3),
1718-
Some(0.4),
1719-
),
1720-
),
1721-
(
1722-
"color(xyz-d65 0.1 0.2 0.3 / 0.4)",
1723-
OutputType::ColorFunction(
1724-
PredefinedColorSpace::XyzD65,
1725-
Some(0.1),
1726-
Some(0.2),
1727-
Some(0.3),
1728-
Some(0.4),
1729-
),
1730-
),
1731-
(
1732-
"color(srgb none none none)",
1733-
OutputType::ColorFunction(PredefinedColorSpace::Srgb, None, None, None, Some(1.0)),
1734-
),
1735-
(
1736-
"color(srgb none none none / none)",
1737-
OutputType::ColorFunction(PredefinedColorSpace::Srgb, None, None, None, None),
1738-
),
1619+
("currentColor", OutputType::CurrentColor),
1620+
("rgb(1, 2, 3)", OutputType::Rgba(1, 2, 3, 1.0)),
1621+
("rgba(1, 2, 3, 0.4)", OutputType::Rgba(1, 2, 3, 0.4)),
1622+
("rgb(none none none / none)", OutputType::Rgba(0, 0, 0, 0.0)),
1623+
("rgb(1 none 3 / none)", OutputType::Rgba(1, 0, 3, 0.0)),
1624+
1625+
("hsla(45deg, 20%, 30%, 0.4)", OutputType::Hsl(Some(45.0), Some(0.2), Some(0.3), Some(0.4))),
1626+
("hsl(45deg none none)", OutputType::Hsl(Some(45.0), None, None, Some(1.0))),
1627+
("hsl(none 10% none / none)", OutputType::Hsl(None, Some(0.1), None, None)),
1628+
("hsl(120 100.0% 50.0%)", OutputType::Hsl(Some(120.0), Some(1.0), Some(0.5), Some(1.0))),
1629+
1630+
("hwb(45deg 20% 30% / 0.4)", OutputType::Hwb(Some(45.0), Some(0.2), Some(0.3), Some(0.4))),
1631+
1632+
("lab(100 20 30 / 0.4)", OutputType::Lab(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
1633+
("lch(100 20 30 / 0.4)", OutputType::Lch(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
1634+
1635+
("oklab(100 20 30 / 0.4)", OutputType::Oklab(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
1636+
("oklch(100 20 30 / 0.4)", OutputType::Oklch(Some(100.0), Some(20.0), Some(30.0), Some(0.4))),
1637+
1638+
("color(srgb 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::Srgb, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
1639+
("color(srgb none none none)", OutputType::ColorFunction(PredefinedColorSpace::Srgb, None, None, None, Some(1.0))),
1640+
("color(srgb none none none / none)", OutputType::ColorFunction(PredefinedColorSpace::Srgb, None, None, None, None)),
1641+
("color(srgb-linear 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::SrgbLinear, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
1642+
("color(display-p3 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::DisplayP3, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
1643+
("color(a98-rgb 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::A98Rgb, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
1644+
("color(prophoto-rgb 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::ProphotoRgb, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
1645+
("color(rec2020 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::Rec2020, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
1646+
("color(xyz-d50 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::XyzD50, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
1647+
("color(xyz-d65 0.1 0.2 0.3 / 0.4)", OutputType::ColorFunction(PredefinedColorSpace::XyzD65, Some(0.1), Some(0.2), Some(0.3), Some(0.4))),
17391648
];
17401649

17411650
for (input, expected) in TESTS {

0 commit comments

Comments
 (0)