helm_template_parser/
lexer.rs1use crate::{error::Error, token::Token};
2
3pub fn tokenize(input: &str) -> Result<Vec<Token>, Error> {
4 let mut tokens = Vec::new();
5
6 let mut iter = input.chars();
7 loop {
8 match iter.next() {
9 Some(c) => {
10 let token = to_token(c)?;
11 tokens.push(token);
12 }
13 None => break,
14 }
15 }
16
17 Ok(tokens)
18}
19
20fn to_token(c: char) -> Result<Token, Error> {
21 match c {
22 letter if letter.is_alphabetic() => Ok(Token::Letter(c)),
23 number if number.is_digit(10) => match number.to_digit(10) {
24 Some(digit) => Ok(Token::Number(digit)),
25 None => Err(Error::LexerError(format!(
26 "failed to convert {} to digit",
27 c
28 ))),
29 },
30 ' ' => Ok(Token::Space),
31 '-' => Ok(Token::Dash),
32 ':' => Ok(Token::Colon),
33 '/' => Ok(Token::Slash),
34 '|' => Ok(Token::Pipe),
35 '.' => Ok(Token::Dot),
36 ',' => Ok(Token::Comma),
37 '\'' => Ok(Token::SingleQuote),
38 '"' => Ok(Token::DoubleQuote),
39 '*' => Ok(Token::Asterisk),
40 '=' => Ok(Token::Equals),
41 '%' => Ok(Token::Percent),
42 '\n' => Ok(Token::Newline),
43 '(' => Ok(Token::LeftParen),
44 ')' => Ok(Token::RightParen),
45 '[' => Ok(Token::LeftBracket),
46 ']' => Ok(Token::RightBracket),
47 '{' => Ok(Token::LeftBrace),
48 '}' => Ok(Token::RightBrace),
49 '$' => Ok(Token::Dollar),
50 _ => Err(Error::LexerError(format!("unrecognized input '{}'", c))),
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn to_token() {
60 let tokens = tokenize("a1 -:/|.,'\"*=%\n()[]{}$").expect("failed to tokenize");
61 assert_eq!(
62 tokens,
63 vec![
64 Token::Letter('a'),
65 Token::Number(1),
66 Token::Space,
67 Token::Dash,
68 Token::Colon,
69 Token::Slash,
70 Token::Pipe,
71 Token::Dot,
72 Token::Comma,
73 Token::SingleQuote,
74 Token::DoubleQuote,
75 Token::Asterisk,
76 Token::Equals,
77 Token::Percent,
78 Token::Newline,
79 Token::LeftParen,
80 Token::RightParen,
81 Token::LeftBracket,
82 Token::RightBracket,
83 Token::LeftBrace,
84 Token::RightBrace,
85 Token::Dollar,
86 ]
87 );
88 }
89}