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.to_string());
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::LABS => "LEFT-ABS",
61 TokenType::RABS => "RIGHT-ABS",
62 };
63
64 String::from(data)
65 }
66}
67
68impl Monitor for Sub {
70 fn to_string(&self, _n: usize) -> String {
71 let data = match &self.method {
72 SubMethod::ABS => "ABSOLUTE-VALUE",
73 SubMethod::PAREN => "PARENTHESES",
74 };
75
76 String::from(data)
77 }
78}
79
80impl Monitor for SubMethod {
82 fn to_string(&self, _n: usize) -> String {
83 let data = match self {
84 SubMethod::ABS => "ABSOLUTE-VALUE",
85 SubMethod::PAREN => "PARENTHESES",
86 };
87
88 String::from(data)
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95 use std::collections::HashMap;
96
97 #[test]
98 fn token_to_string() {
99 let test_data: HashMap<String, String> = HashMap::from([
100 (
101 Token::from(String::from("-25"), (0, 1)).to_string(0),
102 String::from("NUMBER(-25)"),
103 ),
104 (
105 Token::from(String::from("/"), (0, 0)).to_string(0),
106 String::from("DIVIDE(/)"),
107 ),
108 ]);
109
110 for (t, expected) in test_data {
111 assert_eq!(t, expected);
112 }
113 }
114
115 #[test]
116 fn token_type_to_string() {
117 let test_data: HashMap<String, &str> = HashMap::from([
118 (TokenType::NUMBER.to_string(0), "NUMBER"),
119 (TokenType::ILLEGAL.to_string(0), "ILLEGAL"),
120 (TokenType::SUBEXP.to_string(0), "SUB-EXPRESSION"),
121 (TokenType::LPAREN.to_string(0), "LEFT-PARENTHESES"),
122 (TokenType::RPAREN.to_string(0), "RIGHT-PARENTHESES"),
123 (TokenType::POINTER.to_string(0), "POINTER"),
124 (TokenType::PLUS.to_string(0), "PLUS"),
125 (TokenType::MINUS.to_string(0), "MINUS"),
126 (TokenType::PRODUCT.to_string(0), "PRODUCT"),
127 (TokenType::DIVIDE.to_string(0), "DIVIDE"),
128 (TokenType::PERCENTAGE.to_string(0), "PERCENTAGE"),
129 (TokenType::POWER.to_string(0), "POWER"),
130 (TokenType::LABS.to_string(0), "LEFT-ABS"),
131 (TokenType::RABS.to_string(0), "RIGHT-ABS"),
132 ]);
133
134 for (tt, expected) in test_data {
135 assert_eq!(tt, expected);
136 }
137 }
138
139 #[test]
140 fn sub_to_string() {
141 let test_data: HashMap<String, &str> = HashMap::from([
142 (
143 Sub::new(Vec::new(), SubMethod::PAREN).to_string(0),
144 "PARENTHESES",
145 ),
146 (
147 Sub::new(Vec::new(), SubMethod::ABS).to_string(0),
148 "ABSOLUTE-VALUE",
149 ),
150 ]);
151
152 for (s, expected) in test_data {
153 assert_eq!(s, expected);
154 }
155 }
156
157 #[test]
158 fn sub_type_to_string() {
159 let test_data: HashMap<String, &str> = HashMap::from([
160 (SubMethod::PAREN.to_string(0), "PARENTHESES"),
161 (SubMethod::ABS.to_string(0), "ABSOLUTE-VALUE"),
162 ]);
163
164 for (s, expected) in test_data {
165 assert_eq!(s, expected);
166 }
167 }
168}