• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use nom::bytes::complete::{tag, take_while_m_n};
2 use nom::combinator::map_res;
3 use nom::sequence::tuple;
4 use nom::IResult;
5 
6 #[derive(Debug, PartialEq)]
7 pub struct Color {
8   pub red: u8,
9   pub green: u8,
10   pub blue: u8,
11 }
12 
from_hex(input: &str) -> Result<u8, std::num::ParseIntError>13 fn from_hex(input: &str) -> Result<u8, std::num::ParseIntError> {
14   u8::from_str_radix(input, 16)
15 }
16 
is_hex_digit(c: char) -> bool17 fn is_hex_digit(c: char) -> bool {
18   c.is_digit(16)
19 }
20 
hex_primary(input: &str) -> IResult<&str, u8>21 fn hex_primary(input: &str) -> IResult<&str, u8> {
22   map_res(take_while_m_n(2, 2, is_hex_digit), from_hex)(input)
23 }
24 
hex_color(input: &str) -> IResult<&str, Color>25 fn hex_color(input: &str) -> IResult<&str, Color> {
26   let (input, _) = tag("#")(input)?;
27   let (input, (red, green, blue)) = tuple((hex_primary, hex_primary, hex_primary))(input)?;
28 
29   Ok((input, Color { red, green, blue }))
30 }
31 
32 #[test]
parse_color()33 fn parse_color() {
34   assert_eq!(
35     hex_color("#2F14DF"),
36     Ok((
37       "",
38       Color {
39         red: 47,
40         green: 20,
41         blue: 223,
42       }
43     ))
44   );
45 }
46