1 use {
2     super::*,
3     crate::errors::InvalidSkinError,
4     crossterm::style::{
5         Color::{self, *},
6     },
7     lazy_regex::regex_captures,
8 };
9 
10 /// read a color from a string.
11 /// It may be either
12 /// - "none"
13 /// - one of the few known color name. Example: "darkred"
14 /// - grayscale with level in [0,24[. Example: "grey(5)"
15 /// - an Ansi code. Example "ansi(106)"
16 /// - RGB. Example: "rgb(25, 100, 0)"
17 /// This function needs a lowercase string (assuming lowercasing
18 /// has be done before, to ensure case-insensitive parsing)
parse(s: &str) -> Result<Option<Color>, InvalidSkinError>19 pub fn parse(s: &str) -> Result<Option<Color>, InvalidSkinError> {
20     if let Some((_, value)) = regex_captures!(r"^ansi\((?P<value>\d+)\)$", s) {
21         let value = value.parse();
22         if let Ok(value) = value {
23             return Ok(ansi(value)); // all ANSI values are ok
24         } else {
25             return Err(InvalidSkinError::InvalidColor { raw: s.to_owned() });
26         }
27     }
28 
29     if let Some((_, level)) = regex_captures!(r"^gr[ae]y(?:scale)?\((?P<level>\d+)\)$", s) {
30         let level = level.parse();
31         if let Ok(level) = level {
32             if level > 23 {
33                 return Err(InvalidSkinError::InvalidGreyLevel { level });
34             }
35             return Ok(gray(level));
36         } else {
37             return Err(InvalidSkinError::InvalidColor { raw: s.to_owned() });
38         }
39     }
40 
41     if let Some((_, r, g, b)) = regex_captures!(r"^rgb\((?P<r>\d+),\s*(?P<g>\d+),\s*(?P<b>\d+)\)$", s) {
42         if let (Ok(r), Ok(g), Ok(b)) = (r.parse(), g.parse(), b.parse()) {
43             return Ok(rgb(r, g, b));
44         } else {
45             return Err(InvalidSkinError::InvalidColor { raw: s.to_owned() });
46         }
47     }
48 
49     match s {
50         "black" => Ok(Some(AnsiValue(16))),
51         "blue" => Ok(Some(Blue)),
52         "cyan" => Ok(Some(Cyan)),
53         "darkblue" => Ok(Some(DarkBlue)),
54         "darkcyan" => Ok(Some(DarkCyan)),
55         "darkgreen" => Ok(Some(DarkGreen)),
56         "darkmagenta" => Ok(Some(DarkMagenta)),
57         "darkred" => Ok(Some(DarkRed)),
58         "green" => Ok(Some(Green)),
59         "grey" => Ok(Some(Grey)),
60         "magenta" => Ok(Some(Magenta)),
61         "red" => Ok(Some(Red)),
62         "yellow" => Ok(Some(Yellow)),
63         "darkyellow" => Ok(Some(DarkYellow)),
64         "white" => Ok(Some(AnsiValue(231))),
65         "none" => Ok(None),
66         _ => Err(InvalidSkinError::InvalidColor { raw: s.to_owned() }),
67     }
68 }
69 
70