1use noa_parser::acceptor::Acceptor;
2use noa_parser::bytes::primitives::number::Number;
3use noa_parser::bytes::primitives::string::DataString;
4use noa_parser::bytes::token::Token;
5use noa_parser::errors::ParseError::UnexpectedToken;
6use noa_parser::errors::ParseResult;
7use noa_parser::recognizer::recognize;
8use noa_parser::scanner::Scanner;
9use noa_parser::visitor::Visitor;
10
11#[derive(Debug)]
12struct RgbColor(u8, u8, u8);
13#[derive(Debug)]
14struct HexColor(u8, u8, u8);
15struct TupleColor(u8, u8, u8);
16
17enum ColorInternal {
18 Rgb(RgbColor),
19 Hex(HexColor),
20 Tuple(TupleColor),
21}
22
23impl From<ColorInternal> for Color {
24 fn from(value: ColorInternal) -> Self {
25 match value {
26 ColorInternal::Rgb(rgb) => Color(rgb.0, rgb.1, rgb.2),
27 ColorInternal::Hex(hex) => Color(hex.0, hex.1, hex.2),
28 ColorInternal::Tuple(tuple) => Color(tuple.0, tuple.1, tuple.2),
29 }
30 }
31}
32
33impl<'a> Visitor<'a, u8> for TupleColor {
34 fn accept(scanner: &mut Scanner<u8>) -> ParseResult<Self> {
35 recognize(Token::OpenParen, scanner)?;
37 let red = Number::accept(scanner)?.0;
39 recognize(Token::Comma, scanner)?;
41 recognize(Token::Whitespace, scanner)?;
42 let green = Number::accept(scanner)?.0;
44 recognize(Token::Comma, scanner)?;
46 recognize(Token::Whitespace, scanner)?;
47 let blue = Number::accept(scanner)?.0;
49 recognize(Token::CloseParen, scanner)?;
51 Ok(TupleColor(red, green, blue))
52 }
53}
54
55impl<'a> Visitor<'a, u8> for RgbColor {
56 fn accept(scanner: &mut Scanner<u8>) -> ParseResult<Self> {
57 let prefix = DataString::<&str>::accept(scanner)?.0;
58
59 if prefix != "rgb" {
60 return Err(UnexpectedToken);
61 }
62
63 recognize(Token::OpenParen, scanner)?;
65 let red = Number::accept(scanner)?.0;
67 recognize(Token::Comma, scanner)?;
69 recognize(Token::Whitespace, scanner)?;
70 let green = Number::accept(scanner)?.0;
72 recognize(Token::Comma, scanner)?;
74 recognize(Token::Whitespace, scanner)?;
75 let blue = Number::accept(scanner)?.0;
77 recognize(Token::CloseParen, scanner)?;
79 Ok(RgbColor(red, green, blue))
80 }
81}
82
83impl<'a> Visitor<'a, u8> for HexColor {
84 fn accept(scanner: &mut Scanner<u8>) -> ParseResult<Self> {
85 recognize(Token::Sharp, scanner)?;
86 let content = DataString::<&str>::accept(scanner)?.0;
87 let (red, green, blue) = (
88 u8::from_str_radix(&content[0..2], 16)?,
89 u8::from_str_radix(&content[2..4], 16)?,
90 u8::from_str_radix(&content[4..6], 16)?,
91 );
92 Ok(HexColor(red, green, blue))
93 }
94}
95
96#[derive(Debug)]
97#[allow(dead_code)]
98pub struct Color(u8, u8, u8);
99
100impl<'a> Visitor<'a, u8> for Color {
101 fn accept(scanner: &mut Scanner<u8>) -> ParseResult<Self> {
102 let color = Acceptor::new(scanner)
103 .try_or(ColorInternal::Hex)?
104 .try_or(ColorInternal::Rgb)?
105 .try_or(ColorInternal::Tuple)?
106 .finish()
107 .ok_or(UnexpectedToken)?;
108 Ok(color.into())
109 }
110}
111
112fn main() {
113 let data = b"rgb(255, 0, 0)";
114 let mut scanner = Scanner::new(data);
115 let result = Color::accept(&mut scanner);
116 println!("{:?}", result);
117
118 let data = b"#ff0000";
119 let mut scanner = Scanner::new(data);
120 let result = Color::accept(&mut scanner);
121 println!("{:?}", result);
122
123 let data = b"(255, 0, 0)";
124 let mut scanner = Scanner::new(data);
125 let result = Color::accept(&mut scanner);
126 println!("{:?}", result);
127}