Skip to content

Commit f9093b5

Browse files
committed
Remove AbsoluteColor abstraction
This change cleans up the Color enum to better represent the <color> type in the spec and reduce the overall size of the color type.
1 parent d3670a8 commit f9093b5

File tree

3 files changed

+56
-94
lines changed

3 files changed

+56
-94
lines changed

src/color.rs

Lines changed: 37 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -467,10 +467,12 @@ impl ToCss for ColorFunction {
467467
}
468468
}
469469

470-
/// An absolutely specified color.
471-
/// https://w3c.github.io/csswg-drafts/css-color-4/#typedef-absolute-color-base
470+
/// A <color> value.
471+
/// https://drafts.csswg.org/css-color-4/#color-type
472472
#[derive(Clone, Copy, PartialEq, Debug)]
473-
pub enum AbsoluteColor {
473+
pub enum Color {
474+
/// The 'currentcolor' keyword.
475+
CurrentColor,
474476
/// Specify sRGB colors directly by their red/green/blue/alpha chanels.
475477
Rgba(RGBA),
476478
/// Specifies a CIELAB color by CIE Lightness and its a- and b-axis hue
@@ -491,64 +493,19 @@ pub enum AbsoluteColor {
491493
ColorFunction(ColorFunction),
492494
}
493495

494-
impl AbsoluteColor {
495-
/// Return the alpha component of any of the schemes within.
496-
pub fn alpha(&self) -> f32 {
497-
match self {
498-
Self::Rgba(c) => c.alpha,
499-
Self::Lab(c) => c.alpha,
500-
Self::Lch(c) => c.alpha,
501-
Self::Oklab(c) => c.alpha,
502-
Self::Oklch(c) => c.alpha,
503-
Self::ColorFunction(c) => c.alpha,
504-
}
505-
}
506-
}
507-
508-
impl ToCss for AbsoluteColor {
509-
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
510-
where
511-
W: fmt::Write,
512-
{
513-
match self {
514-
Self::Rgba(rgba) => rgba.to_css(dest),
515-
Self::Lab(lab) => lab.to_css(dest),
516-
Self::Lch(lch) => lch.to_css(dest),
517-
Self::Oklab(lab) => lab.to_css(dest),
518-
Self::Oklch(lch) => lch.to_css(dest),
519-
Self::ColorFunction(color_function) => color_function.to_css(dest),
520-
}
521-
}
522-
}
523-
524-
#[inline]
525-
pub(crate) const fn rgb(red: u8, green: u8, blue: u8) -> Color {
526-
rgba(red, green, blue, OPAQUE)
527-
}
528-
529-
#[inline]
530-
pub(crate) const fn rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Color {
531-
Color::Absolute(AbsoluteColor::Rgba(RGBA::new(red, green, blue, alpha)))
532-
}
533-
534-
/// A <color> value.
535-
/// https://w3c.github.io/csswg-drafts/css-color-4/#color-type
536-
#[derive(Clone, Copy, PartialEq, Debug)]
537-
pub enum Color {
538-
/// The 'currentcolor' keyword.
539-
CurrentColor,
540-
/// An absolutely specified color.
541-
Absolute(AbsoluteColor),
542-
}
543-
544496
impl ToCss for Color {
545497
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
546498
where
547499
W: fmt::Write,
548500
{
549501
match *self {
550502
Color::CurrentColor => dest.write_str("currentcolor"),
551-
Color::Absolute(absolute) => absolute.to_css(dest),
503+
Color::Rgba(rgba) => rgba.to_css(dest),
504+
Color::Lab(lab) => lab.to_css(dest),
505+
Color::Lch(lch) => lch.to_css(dest),
506+
Color::Oklab(lab) => lab.to_css(dest),
507+
Color::Oklch(lch) => lch.to_css(dest),
508+
Color::ColorFunction(color_function) => color_function.to_css(dest),
552509
}
553510
}
554511
}
@@ -686,8 +643,9 @@ impl Color {
686643
let location = input.current_source_location();
687644
let token = input.next()?;
688645
match *token {
689-
Token::Hash(ref value) | Token::IDHash(ref value) => RGBA::parse_hash(value.as_bytes())
690-
.map(|rgba| Color::Absolute(AbsoluteColor::Rgba(rgba))),
646+
Token::Hash(ref value) | Token::IDHash(ref value) => {
647+
RGBA::parse_hash(value.as_bytes()).map(|rgba| Color::Rgba(rgba))
648+
}
691649
Token::Ident(ref value) => parse_color_keyword(&*value),
692650
Token::Function(ref name) => {
693651
let name = name.clone();
@@ -714,6 +672,16 @@ impl Color {
714672
/// (For example, the value of an `Ident` token is fine.)
715673
#[inline]
716674
pub fn parse_color_keyword(ident: &str) -> Result<Color, ()> {
675+
#[inline]
676+
pub(crate) const fn rgb(red: u8, green: u8, blue: u8) -> Color {
677+
rgba(red, green, blue, OPAQUE)
678+
}
679+
680+
#[inline]
681+
pub(crate) const fn rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Color {
682+
Color::Rgba(RGBA::new(red, green, blue, alpha))
683+
}
684+
717685
ascii_case_insensitive_phf_map! {
718686
keyword -> Color = {
719687
"black" => rgb(0, 0, 0),
@@ -927,25 +895,25 @@ where
927895
// for L: 0% = 0.0, 100% = 100.0
928896
// for a and b: -100% = -125, 100% = 125
929897
"lab" => parse_lab_like(component_parser, arguments, 100.0, 125.0, |l, a, b, alpha| {
930-
Color::Absolute(AbsoluteColor::Lab(Lab::new(l.max(0.), a , b , alpha)))
898+
Color::Lab(Lab::new(l.max(0.), a , b , alpha))
931899
}),
932900

933901
// for L: 0% = 0.0, 100% = 100.0
934902
// for C: 0% = 0, 100% = 150
935903
"lch" => parse_lch_like(component_parser, arguments, 100.0, 150.0, |l, c, h, alpha| {
936-
Color::Absolute(AbsoluteColor::Lch(Lch::new(l.max(0.), c.max(0.), h, alpha)))
904+
Color::Lch(Lch::new(l.max(0.), c.max(0.), h, alpha))
937905
}),
938906

939907
// for L: 0% = 0.0, 100% = 1.0
940908
// for a and b: -100% = -0.4, 100% = 0.4
941909
"oklab" => parse_lab_like(component_parser, arguments, 1.0, 0.4, |l, a, b, alpha| {
942-
Color::Absolute(AbsoluteColor::Oklab(Oklab::new(l.max(0.), a, b, alpha)))
910+
Color::Oklab(Oklab::new(l.max(0.), a, b, alpha))
943911
}),
944912

945913
// for L: 0% = 0.0, 100% = 1.0
946914
// for C: 0% = 0.0 100% = 0.4
947915
"oklch" => parse_lch_like(component_parser, arguments, 1.0, 0.4, |l, c, h, alpha| {
948-
Color::Absolute(AbsoluteColor::Oklch(Oklch::new(l.max(0.), c.max(0.), h, alpha)))
916+
Color::Oklch(Oklch::new(l.max(0.), c.max(0.), h, alpha))
949917
}),
950918

951919
"color" => parse_color_function(component_parser, arguments),
@@ -1029,7 +997,7 @@ where
1029997
ComponentParser: ColorComponentParser<'i>,
1030998
{
1031999
let (red, green, blue, alpha) = parse_rgb_components_rgb(component_parser, arguments)?;
1032-
Ok(rgba(red, green, blue, alpha))
1000+
Ok(Color::Rgba(RGBA::new(red, green, blue, alpha)))
10331001
}
10341002

10351003
/// Parses hsl and hbw syntax, which happens to be identical.
@@ -1076,7 +1044,7 @@ where
10761044

10771045
let alpha = parse_alpha(component_parser, arguments, uses_commas)?;
10781046

1079-
Ok(rgba(red, green, blue, alpha))
1047+
Ok(Color::Rgba(RGBA::new(red, green, blue, alpha)))
10801048
}
10811049

10821050
/// https://drafts.csswg.org/css-color-4/#hwb-to-rgb
@@ -1223,13 +1191,11 @@ where
12231191

12241192
let alpha = parse_alpha(component_parser, arguments, false)?;
12251193

1226-
Ok(Color::Absolute(AbsoluteColor::ColorFunction(
1227-
ColorFunction {
1228-
color_space,
1229-
c1,
1230-
c2,
1231-
c3,
1232-
alpha,
1233-
},
1234-
)))
1194+
Ok(Color::ColorFunction(ColorFunction {
1195+
color_space,
1196+
c1,
1197+
c2,
1198+
c3,
1199+
alpha,
1200+
}))
12351201
}

src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,8 @@ fn parse_border_spacing(_context: &ParserContext, input: &mut Parser)
6868
#![recursion_limit = "200"] // For color::parse_color_keyword
6969

7070
pub use crate::color::{
71-
hsl_to_rgb, hwb_to_rgb, parse_color_keyword, AbsoluteColor, AngleOrNumber, Color,
72-
ColorComponentParser, ColorFunction, Lab, Lch, NumberOrPercentage, Oklab, Oklch,
73-
PredefinedColorSpace, RGBA,
71+
hsl_to_rgb, hwb_to_rgb, parse_color_keyword, AngleOrNumber, Color, ColorComponentParser,
72+
ColorFunction, Lab, Lch, NumberOrPercentage, Oklab, Oklch, PredefinedColorSpace, RGBA,
7473
};
7574
pub use crate::cow_rc_str::CowRcStr;
7675
pub use crate::from_bytes::{stylesheet_encoding, EncodingSupport};

src/tests.rs

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@ use serde_json::{self, json, Map, Value};
1212
use self::test::Bencher;
1313

1414
use super::{
15-
color::{rgb, rgba},
1615
parse_important, parse_nth, parse_one_declaration, parse_one_rule, stylesheet_encoding,
17-
AbsoluteColor, AtRuleParser, BasicParseError, BasicParseErrorKind, Color, CowRcStr,
18-
DeclarationListParser, DeclarationParser, Delimiter, EncodingSupport, ParseError,
19-
ParseErrorKind, Parser, ParserInput, ParserState, QualifiedRuleParser, RuleListParser,
20-
SourceLocation, ToCss, Token, TokenSerializationType, UnicodeRange, RGBA,
16+
AtRuleParser, BasicParseError, BasicParseErrorKind, Color, CowRcStr, DeclarationListParser,
17+
DeclarationParser, Delimiter, EncodingSupport, ParseError, ParseErrorKind, Parser, ParserInput,
18+
ParserState, QualifiedRuleParser, RuleListParser, SourceLocation, ToCss, Token,
19+
TokenSerializationType, UnicodeRange, RGBA,
2120
};
2221

2322
macro_rules! JArray {
@@ -590,19 +589,19 @@ fn serialize_current_color() {
590589

591590
#[test]
592591
fn serialize_rgb_full_alpha() {
593-
let c = rgb(255, 230, 204);
592+
let c = Color::Rgba(RGBA::new(255, 230, 204, 1.0));
594593
assert_eq!(c.to_css_string(), "rgb(255, 230, 204)");
595594
}
596595

597596
#[test]
598597
fn serialize_rgba() {
599-
let c = rgba(26, 51, 77, 0.125);
598+
let c = Color::Rgba(RGBA::new(26, 51, 77, 0.125));
600599
assert_eq!(c.to_css_string(), "rgba(26, 51, 77, 0.125)");
601600
}
602601

603602
#[test]
604603
fn serialize_rgba_two_digit_float_if_roundtrips() {
605-
let c = Color::Absolute(AbsoluteColor::Rgba(RGBA::from_floats(0., 0., 0., 0.5)));
604+
let c = Color::Rgba(RGBA::from_floats(0., 0., 0., 0.5));
606605
assert_eq!(c.to_css_string(), "rgba(0, 0, 0, 0.5)");
607606
}
608607

@@ -895,18 +894,16 @@ impl ToJson for Color {
895894
fn to_json(&self) -> Value {
896895
match *self {
897896
Color::CurrentColor => "currentcolor".to_json(),
898-
Color::Absolute(absolute) => match absolute {
899-
AbsoluteColor::Rgba(ref rgba) => {
900-
json!([rgba.red, rgba.green, rgba.blue, rgba.alpha])
901-
}
902-
AbsoluteColor::Lab(ref c) => json!([c.lightness, c.a, c.b, c.alpha]),
903-
AbsoluteColor::Lch(ref c) => json!([c.lightness, c.chroma, c.hue, c.alpha]),
904-
AbsoluteColor::Oklab(ref c) => json!([c.lightness, c.a, c.b, c.alpha]),
905-
AbsoluteColor::Oklch(ref c) => json!([c.lightness, c.chroma, c.hue, c.alpha]),
906-
AbsoluteColor::ColorFunction(ref c) => {
907-
json!([c.color_space.as_str(), c.c1, c.c2, c.c3, c.alpha])
908-
}
909-
},
897+
Color::Rgba(ref rgba) => {
898+
json!([rgba.red, rgba.green, rgba.blue, rgba.alpha])
899+
}
900+
Color::Lab(ref c) => json!([c.lightness, c.a, c.b, c.alpha]),
901+
Color::Lch(ref c) => json!([c.lightness, c.chroma, c.hue, c.alpha]),
902+
Color::Oklab(ref c) => json!([c.lightness, c.a, c.b, c.alpha]),
903+
Color::Oklch(ref c) => json!([c.lightness, c.chroma, c.hue, c.alpha]),
904+
Color::ColorFunction(ref c) => {
905+
json!([c.color_space.as_str(), c.c1, c.c2, c.c3, c.alpha])
906+
}
910907
}
911908
}
912909
}

0 commit comments

Comments
 (0)