1use nom::bytes::complete::{tag, take_while_m_n}; 2use nom::combinator::map_res; 3use nom::sequence::tuple; 4use nom::IResult; 5 6#[derive(Debug, PartialEq)] 7pub struct Color { 8 pub red: u8, 9 pub green: u8, 10 pub blue: u8, 11} 12 13fn from_hex(input: &str) -> Result<u8, std::num::ParseIntError> { 14 u8::from_str_radix(input, 16) 15} 16 17fn is_hex_digit(c: char) -> bool { 18 c.is_digit(16) 19} 20 21fn hex_primary(input: &str) -> IResult<&str, u8> { 22 map_res(take_while_m_n(2, 2, is_hex_digit), from_hex)(input) 23} 24 25fn 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] 33fn 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