1use crate::token::{Sub, SubMethod, Token, TokenType};
8
9pub trait Monitor {
10 fn to_string(&self, n: usize) -> String;
13}
14
15impl Monitor for Token {
17 fn to_string(&self, n: usize) -> String {
18 let mut lit: String;
19 let mut space: String = String::new();
20
21 let nest: usize = n;
22 if self.typ != TokenType::SUBEXP {
23 lit = format!("({})", self.literal);
24 } else {
25 lit = String::new();
26 for t in self.sub.tokens.iter().map(|t| t.to_string(nest + 1)) {
27 lit.push_str(format!("\n{t}").as_str())
28 }
29 }
30
31 for _ in 0..nest {
32 space.push_str(" ");
33 }
34
35 let mut typstr = self.typ.to_string(0);
36 if self.is_sub_exp() {
37 typstr.push_str(format!(" -> {{{}}}", self.sub.to_string(0)).as_str());
38 }
39
40 format!("{}{}{}", space.as_str(), typstr, lit)
41 }
42}
43
44impl Monitor for TokenType {
46 fn to_string(&self, _n: usize) -> String {
47 let data = match self {
48 TokenType::NUMBER => "NUMBER",
49 TokenType::ILLEGAL => "ILLEGAL",
50 TokenType::SUBEXP => "SUB-EXPRESSION",
51 TokenType::LPAREN => "LEFT-PARENTHESES",
52 TokenType::RPAREN => "RIGHT-PARENTHESES",
53 TokenType::POINTER => "POINTER",
54 TokenType::PLUS => "PLUS",
55 TokenType::MINUS => "MINUS",
56 TokenType::PRODUCT => "PRODUCT",
57 TokenType::DIVIDE => "DIVIDE",
58 TokenType::PERCENTAGE => "PERCENTAGE",
59 TokenType::POWER => "POWER",
60 TokenType::FACTORIAL => "FACTORIAL",
61 TokenType::LABS => "LEFT-ABS",
62 TokenType::RABS => "RIGHT-ABS",
63 TokenType::SQRT => "SQRT",
64 TokenType::SIN => "SIN",
65 TokenType::COS => "COS",
66 TokenType::TAN => "TAN",
67 TokenType::LOG => "LOG",
68 TokenType::LN => "LN",
69 TokenType::EXP => "EXP",
70 TokenType::FLOOR => "FLOOR",
71 TokenType::CEIL => "CEIL",
72 TokenType::ROUND => "ROUND",
73 };
74
75 String::from(data)
76 }
77}
78
79impl Monitor for Sub {
81 fn to_string(&self, _n: usize) -> String {
82 let data = match &self.method {
83 SubMethod::ABS => "ABSOLUTE-VALUE",
84 SubMethod::PAREN => "PARENTHESES",
85 };
86
87 String::from(data)
88 }
89}
90
91impl Monitor for SubMethod {
93 fn to_string(&self, _n: usize) -> String {
94 let data = match self {
95 SubMethod::ABS => "ABSOLUTE-VALUE",
96 SubMethod::PAREN => "PARENTHESES",
97 };
98
99 String::from(data)
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106 use std::collections::HashMap;
107
108 #[test]
109 fn token_to_string() {
110 let test_data: HashMap<String, String> = HashMap::from([
111 (
112 Token::from(String::from("-25"), (0, 1)).to_string(0),
113 String::from("NUMBER(-25)"),
114 ),
115 (
116 Token::from(String::from("/"), (0, 0)).to_string(0),
117 String::from("DIVIDE(/)"),
118 ),
119 ]);
120
121 for (t, expected) in test_data {
122 assert_eq!(t, expected);
123 }
124 }
125
126 #[test]
127 fn token_type_to_string() {
128 let test_data: HashMap<String, &str> = HashMap::from([
129 (TokenType::NUMBER.to_string(0), "NUMBER"),
130 (TokenType::ILLEGAL.to_string(0), "ILLEGAL"),
131 (TokenType::SUBEXP.to_string(0), "SUB-EXPRESSION"),
132 (TokenType::LPAREN.to_string(0), "LEFT-PARENTHESES"),
133 (TokenType::RPAREN.to_string(0), "RIGHT-PARENTHESES"),
134 (TokenType::POINTER.to_string(0), "POINTER"),
135 (TokenType::PLUS.to_string(0), "PLUS"),
136 (TokenType::MINUS.to_string(0), "MINUS"),
137 (TokenType::PRODUCT.to_string(0), "PRODUCT"),
138 (TokenType::DIVIDE.to_string(0), "DIVIDE"),
139 (TokenType::PERCENTAGE.to_string(0), "PERCENTAGE"),
140 (TokenType::POWER.to_string(0), "POWER"),
141 (TokenType::LABS.to_string(0), "LEFT-ABS"),
142 (TokenType::RABS.to_string(0), "RIGHT-ABS"),
143 ]);
144
145 for (tt, expected) in test_data {
146 assert_eq!(tt, expected);
147 }
148 }
149
150 #[test]
151 fn sub_to_string() {
152 let test_data: HashMap<String, &str> = HashMap::from([
153 (
154 Sub::new(Vec::new(), SubMethod::PAREN).to_string(0),
155 "PARENTHESES",
156 ),
157 (
158 Sub::new(Vec::new(), SubMethod::ABS).to_string(0),
159 "ABSOLUTE-VALUE",
160 ),
161 ]);
162
163 for (s, expected) in test_data {
164 assert_eq!(s, expected);
165 }
166 }
167
168 #[test]
169 fn sub_type_to_string() {
170 let test_data: HashMap<String, &str> = HashMap::from([
171 (SubMethod::PAREN.to_string(0), "PARENTHESES"),
172 (SubMethod::ABS.to_string(0), "ABSOLUTE-VALUE"),
173 ]);
174
175 for (s, expected) in test_data {
176 assert_eq!(s, expected);
177 }
178 }
179}