1use super::operator::*;
2
3#[derive(Debug, Clone, Copy, PartialEq)]
4pub enum Token {
5 Num(f64),
6 Op(Op),
7 ParL,
8 ParR,
9 Var(char),
10}
11
12#[derive(Debug, PartialEq)]
13pub enum TokenParseError {
14 IsDigit,
15 IsPunctuation,
16}
17
18impl Token {
19 pub fn parse(c: &char) -> Result<Self, TokenParseError> {
20 if c.is_ascii_digit() {
21 Err(TokenParseError::IsDigit)
22 } else if Op::is_valid(c) {
23 Ok(Token::Op(Op::parse(c).unwrap()))
24 } else if *c == '(' || *c == '[' || *c == '{' {
25 Ok(Token::ParL)
26 } else if *c == ')' || *c == ']' || *c == '}' {
27 Ok(Token::ParR)
28 } else if c.is_ascii_punctuation() {
29 Err(TokenParseError::IsPunctuation)
30 } else {
31 Ok(Token::Var(*c))
32 }
33 }
34
35 pub fn is_valid(c: &char) -> bool {
36 let is_paren =
37 |c: &char| *c == '(' || *c == '[' || *c == '{' || *c == ')' || *c == ']' || *c == '}';
38
39 !(c.is_ascii_digit() || (c.is_ascii_punctuation() && !(Op::is_valid(c) || is_paren(c))))
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn is_valid_1() {
49 assert!(Token::is_valid(&'a'));
50 }
51
52 #[test]
53 fn is_valid_2() {
54 assert!(Token::is_valid(&'Z'));
55 }
56
57 #[test]
58 fn is_valid_4() {
59 assert!(Token::is_valid(&'('));
60 }
61
62 #[test]
63 fn is_valid_5() {
64 assert!(Token::is_valid(&')'));
65 }
66
67 #[test]
68 fn is_valid_6() {
69 assert!(Token::is_valid(&'+'));
70 }
71
72 #[test]
73 fn is_valid_7() {
74 assert!(!Token::is_valid(&'1'));
75 }
76
77 #[test]
78 fn is_valid_8() {
79 assert!(!Token::is_valid(&'!'));
80 }
81
82 #[test]
83 fn is_valid_9() {
84 assert!(!Token::is_valid(&','));
85 }
86
87 #[test]
88 fn is_valid_3() {
89 assert!(!Token::is_valid(&'_'));
90 }
91}