1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
use super::converters::hex_num_to_rgb; use super::error::{ make_def_parse_err, make_hex_parse_err, make_hsl_parse_err, make_hsla_parse_err, make_rgb_parse_err, make_rgba_parse_err, ParseError, }; use super::{ColorTuple, ColorTupleA}; pub fn hex(s: &str) -> Result<ColorTuple, ParseError> { let mut hex = s.replace("#", "").to_lowercase(); let count = hex.chars().count(); if count == 3 { hex = hex.chars().map(|c| c.to_string().repeat(2)).collect::<Vec<String>>().join(""); } else if count != 6 { return Err(make_hex_parse_err(s)); } match usize::from_str_radix(&hex, 16) { Ok(num) => Ok(hex_num_to_rgb(num)), Err(_) => Err(make_hex_parse_err(s)), } } fn clear_str(s: &str) -> String { let mut result = s.to_lowercase(); for p in ["rgba", "rgb", "hsla", "hsl", "(", ")", "%", " "].iter() { result = result.replace(p, ""); } result } fn collect_vec_and_parse(s: &str) -> Result<Vec<f32>, std::num::ParseFloatError> { let v = s.split(',').map(|c| c.to_string()).collect::<Vec<String>>(); let mut units = Vec::new(); for unit in v { let u = unit.parse::<f32>()?; units.push(u); } Ok(units) } fn parse_color_tuple(s: &str) -> Result<ColorTuple, ParseError> { match collect_vec_and_parse(&clear_str(s)) { Ok(num_vec) => { if num_vec.len() != 3 { Err(make_def_parse_err(&s)) } else { Ok((num_vec[0], num_vec[1], num_vec[2])) } } Err(_) => Err(make_def_parse_err(&s)), } } fn parse_color_tuple_a(s: &str) -> Result<ColorTupleA, ParseError> { match collect_vec_and_parse(&clear_str(s)) { Ok(num_vec) => { if num_vec.len() != 4 { Err(make_def_parse_err(&s)) } else { Ok((num_vec[0], num_vec[1], num_vec[2], num_vec[3])) } } Err(_) => Err(make_def_parse_err(&s)), } } pub fn rgb(s: &str) -> Result<ColorTuple, ParseError> { match parse_color_tuple(s) { Err(_) => Err(make_rgb_parse_err(s)), Ok(rgb) => Ok(rgb), } } pub fn rgba(s: &str) -> Result<ColorTupleA, ParseError> { match parse_color_tuple_a(s) { Err(_) => Err(make_rgba_parse_err(s)), Ok(rgba) => Ok(rgba), } } pub fn hsl(s: &str) -> Result<ColorTuple, ParseError> { match parse_color_tuple(s) { Err(_) => Err(make_hsl_parse_err(s)), Ok(hsl) => Ok(hsl), } } pub fn hsla(s: &str) -> Result<ColorTupleA, ParseError> { match parse_color_tuple_a(s) { Err(_) => Err(make_hsla_parse_err(s)), Ok(hsla) => Ok(hsla), } }