Skip to content

Commit c097afd

Browse files
committed
add working rgb and rgba parsing
1 parent 8f280dd commit c097afd

File tree

1 file changed

+12
-54
lines changed

1 file changed

+12
-54
lines changed

src/color/parse.rs

Lines changed: 12 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
use core::fmt;
44

5-
use anyhow::Ok;
6-
75
use crate::color::{ColorFloat, model::Color};
86

97
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -344,51 +342,6 @@ fn parse_css_rgb(args: &str) -> Result<Color, ColorParseError> {
344342
Ok(Color::from_rgba([r, g, b, a]))
345343
}
346344

347-
/// Parse a CSS rgba function.
348-
///
349-
/// The allowed styles are:
350-
/// rgba(r,g,b,a)
351-
/// rgba(r g b a) (TODO: needs implementation)
352-
/// rgba(r% g% b% a%) (TODO: needs implementation)
353-
/// rgba(r g b / a) (TODO: needs implementation)
354-
fn parse_css_rgba(args: &str) -> Result<Color, ColorParseError> {
355-
use ColorParseError::*;
356-
357-
let nums: Vec<&str> = args.split(',').map(|t| t.trim()).collect();
358-
if nums.len() != 4 {
359-
return Err(InvalidFunc);
360-
}
361-
362-
let r = nums[0]
363-
.parse::<u16>()
364-
.ok()
365-
.filter(|&v| v <= 255)
366-
.ok_or(OutOfRange)? as u8;
367-
let g = nums[1]
368-
.parse::<u16>()
369-
.ok()
370-
.filter(|&v| v <= 255)
371-
.ok_or(OutOfRange)? as u8;
372-
let b = nums[2]
373-
.parse::<u16>()
374-
.ok()
375-
.filter(|&v| v <= 255)
376-
.ok_or(OutOfRange)? as u8;
377-
378-
// allow 0.0..1.0 or 0..255
379-
let a = if let Ok(f) = nums[3].parse::<f32>() {
380-
(f.clamp(0.0, 1.0) * 255.0 + 0.5).floor() as u8
381-
} else {
382-
nums[3]
383-
.parse::<u16>()
384-
.ok()
385-
.filter(|&v| v <= 255)
386-
.ok_or(OutOfRange)? as u8
387-
};
388-
389-
Ok(Color::from_rgba([r, g, b, a]))
390-
}
391-
392345
pub fn parse_color(mut s: &str) -> Result<Color, ColorParseError> {
393346
use ColorParseError::*;
394347

@@ -397,12 +350,6 @@ pub fn parse_color(mut s: &str) -> Result<Color, ColorParseError> {
397350
}
398351
s = s.trim();
399352

400-
// Hex-like
401-
if let Some(rest) = s.strip_prefix('#') {
402-
let hex = rest.trim();
403-
return parse_hex(hex);
404-
}
405-
406353
// CSS-like: rgb(r,g,b) / rgba(r,g,b,a[0..1])
407354
// TODO: Parsing support is “CSS2-ish” right now
408355
// We only handle rgb(r,g,b) and rgba(r,g,b,a) with integers and commas. Modern CSS allows:
@@ -414,16 +361,27 @@ pub fn parse_color(mut s: &str) -> Result<Color, ColorParseError> {
414361
// We already have HSL converters, so once the parser extracts (h, s%, l%, a?), we can call from_hsl.
415362
// Also allow for things like rgb(+255, +255, +255) (CSS allowed)
416363
let lower = s.to_ascii_lowercase();
364+
417365
if let Some(args) = lower.strip_prefix("rgb(").and_then(|x| x.strip_suffix(')')) {
418366
return parse_css_rgb(args);
419367
}
368+
// rgba() in CSS is just rgb() with the same arg grammar in modern CSS
420369
if let Some(args) = lower
421370
.strip_prefix("rgba(")
422371
.and_then(|x| x.strip_suffix(')'))
423372
{
424-
return parse_css_rgba(args);
373+
return parse_css_rgb(args);
425374
}
426375

376+
// Hex-like
377+
if let Some(rest) = s.strip_prefix('#') {
378+
let hex = rest.trim();
379+
return parse_hex(hex);
380+
}
381+
382+
// try hex without '#'
383+
// TODO
384+
427385
Err(InvalidFunc)
428386
}
429387

0 commit comments

Comments
 (0)