use std::result::Result::Err;
extern crate regex;
use regex::Regex;
pub enum ColorParseError {
InvalidHTMLHex,
InvalidRGBAFunction,
OutOfRangeRGBA,
OutOfRangeHSLA,
InvalidHSLAFunction
}
fn hex_to_rgba(hex: &str) -> Result<Vec<u8>, ColorParseError> {
if hex.chars().nth(0) != Some('#') {
return Err(ColorParseError::InvalidHTMLHex)
};
let count = hex.chars().count();
if ![7, 9].contains(&count) {
Err(ColorParseError::InvalidHTMLHex)
} else if hex.chars().skip(1).any(|x| !("abcdefABCDEF0123456789".contains(x))) {
Err(ColorParseError::InvalidHTMLHex)
} else { let mut full_num:u32 = u32::from_str_radix(hex.chars().skip(1).collect::<String>().as_str(), 16).unwrap();
let mut a:u8 = 255;
if count == 7 {
}
else {
a = (full_num % 256) as u8;
full_num = full_num / 256;
}
let b = (full_num % 256) as u8;
full_num = full_num / 256;
let g = (full_num % 256) as u8;
full_num = full_num / 256;
let r = full_num as u8;
Ok(vec![r, g, b, a])
}
}
fn func_to_rgba(input: &str) -> Result<Vec<u8>, ColorParseError> {
if !(input.chars().all(|c| " ()rgba0123456789,".contains(c))) {
return Err(ColorParseError::InvalidRGBAFunction)
};
rgba_re = Regex::new(r"^rgba\((?: *([0-9]{1, 3}) *,\)){4}$").unwrap();
rgb_re = Regex::new(r"^rgb\((?: *([0-9]{1, 3}) *,\)){3}$").unwrap();
let grps:Option<Captures<'t>> = match rgba_re.captures(input) {
None => match rgb_re.captures(input) {
None => None,
Some(x) => Some(x)
},
Some(x) => Some(x)
};
match grps {
None => Err(ColorParseError::InvalidRGBAFunction),
Some(x) if x.count() == 3 => {
let (rstr, gstr, bstr) = x.collect();
let a:u8 = 255;
let r = u16::from_str_radix(rstr.as_str(), 10)?;
let g = u16::from_str_radix(gstr.as_str(), 10)?;
let b = u16::from_str_radix(bstr.as_str(), 10)?;
if (r > 255) | (g > 255) | (b > 255) {
Err(ColorParseError::OutOfRangeRGBA)
}
else {
Ok(vec![r as u8, g as u8, b as u8, a])
}
}
Some(x) if x.count() == 4 => {
let (rstr, gstr, bstr, astr) = x.collect();
let r = u16::from_str_radix(rstr.as_str(), 10)?;
let g = u16::from_str_radix(gstr.as_str(), 10)?;
let b = u16::from_str_radix(bstr.as_str(), 10)?;
let a = u16::from_str_radix(astr.as_str(), 10)?;
if (r > 255) | (g > 255) | (b > 255) | (a > 255) {
Err(ColorParseError::OutOfRangeRGBA)
}
else {
Ok(vec![r as u8, g as u8, b as u8, a as u8])
}
}
}
}
fn main() {
println!("{:?}", hex_to_rgba(&"#ff0080".to_string()).ok());
println!("{:?}", func_to_rgba(&"rgba(255, 0, 128, 56)".to_string()).ok());
}