Skip to content

Generic color parser #318

Closed
Closed
@tiaanl

Description

@tiaanl

I would like to abstract the color parsing to allow construction of any kind of color value. Currently color parsing is based around the color::Color struct:

let color = Color::parse(&component_parser, input);

This is good when you want the details from the parsed color, but the data contained in the Color type is not ideal for calculations like color space conversions, interpolation, etc.

Rather than tweak the fields in the color type to work better for any use, I propose to extract the parsing code into a more generic parser that can construct any kind of color value. Benefits:

  • Parsing of color values does not dictate the format of data you get out.
  • Avoids having the data parsed into one format and then converted into another.
  • When adding more complex parsing, like none values, relative color syntax, etc. the Color type will get even more complex and further away from a calculation friendly format.
  • Increases stability of the color parsing API for third parties.

Example interface:

pub trait ColorFactory {
    fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self;
    fn from_lab(lightness: f32, a: f32, b: f32, alpha: f32) -> Self;
    fn from_current_color() -> Self;
}

pub fn parse_color<'i, 't, ComponentParser, C>(
    component_parser: &ComponentParser,
    input: &mut Parser<'i, 't>,
) -> Result<Color, ParseError<'i, ComponentParser::Error>>
where
    ComponentParser: ColorComponentParser<'i>,
    C: ColorFactory,
{
    todo!()
}

and users of the library would have:

enum MyColor {
    CurrentColor,
    Rgba(u8, u8, u8, f32),
    Lab(f32, f32, f32, f32),
}

impl ColorFactory for MyColor {
    fn from_rgba(red: u8, green: u8, blue: u8, alpha: f32) -> Self {
        todo!()
    }
    fn from_lab(lightness: f32, a: f32, b: f32, alpha: f32) -> Self {
        todo!()
    }
    fn from_current_color() -> Self {
        todo!()
    }
}

let color: MyColor = parse_color(&component_parser, input);

Thoughts are super welcome.

Ping @emilio @GPHemsley

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions