tiny_json_rs/mapper/
mod.rs1use crate::lexer::{StringType, Token, TokenType};
2use alloc::collections::BTreeMap;
3use alloc::string::String;
4use alloc::vec::Vec;
5use core::fmt::Display;
6
7pub type Object = BTreeMap<String, Value>;
8
9#[derive(Debug, PartialEq, Clone)]
10pub enum Value {
11 Token(Token),
12 Object(Object),
13 Array(Vec<Value>),
14}
15
16impl Display for Value {
17 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
18 match self {
19 Value::Token(token) => write!(f, "{}", token.literal),
20 Value::Object(object) => write!(f, "{:?}", object),
21 Value::Array(array) => write!(f, "{:?}", array),
22 }
23 }
24}
25
26#[derive(Debug, PartialEq)]
27pub enum MapperError {
28 UnexpectedToken(Token),
29}
30
31pub struct Mapper {
32 pub token_list: Vec<Token>,
33 pub position: usize,
34}
35
36impl Mapper {
37 pub fn new(token_list: Vec<Token>) -> Self {
38 Mapper {
39 token_list,
40 position: 0,
41 }
42 }
43
44 fn read_token(&mut self) -> Token {
45 let token = self.token_list[self.position].clone();
46 self.position += 1;
47 token
48 }
49
50 fn peek_token(&mut self) -> Token {
51 self.token_list[self.position].clone()
52 }
53
54 fn expect(&mut self, token_type: TokenType) -> Result<Token, MapperError> {
55 let token = self.read_token();
56 if token.token_type != token_type {
57 return Err(MapperError::UnexpectedToken(token));
58 }
59 Ok(token)
60 }
61
62 fn parse_array(&mut self) -> Result<Vec<Value>, MapperError> {
63 let mut array = Vec::new();
64 self.expect(TokenType::LBracket)?; loop {
66 let token = self.peek_token();
67 if token.token_type == TokenType::RBracket {
68 break;
69 }
70
71 if token.token_type == TokenType::LBrace {
72 let object = self.parse_object()?;
73 array.push(Value::Object(object));
74 } else {
75 let token = self.read_token();
76 array.push(Value::Token(token));
77 }
78
79 let token = self.read_token();
80 match token.token_type {
81 TokenType::Comma => continue,
82 TokenType::RBracket => break,
83 _ => return Err(MapperError::UnexpectedToken(token)),
84 }
85 }
86 Ok(array)
87 }
88
89 fn parse_value(&mut self) -> Result<(String, Value), MapperError> {
90 let key_token = self.expect(TokenType::String(StringType::SimpleString))?;
91 self.expect(TokenType::Colon)?;
92 let value_token = self.read_token();
93 return match value_token.token_type {
94 TokenType::String(_) => {
95 let value = Value::Token(value_token);
96 Ok((key_token.literal, value))
97 }
98 TokenType::Int | TokenType::Float | TokenType::ReservedString => {
99 let value = Value::Token(value_token);
100 Ok((key_token.literal, value))
101 }
102 TokenType::LBrace => {
103 self.position -= 1;
104 let value = Value::Object(self.parse_object()?);
105 Ok((key_token.literal, value))
106 }
107 TokenType::LBracket => {
108 self.position -= 1;
109 let value = Value::Array(self.parse_array()?);
110 Ok((key_token.literal, value))
111 }
112 _ => Err(MapperError::UnexpectedToken(value_token)),
113 };
114 }
115
116 pub fn parse_object(&mut self) -> Result<Object, MapperError> {
117 let mut object = BTreeMap::new();
118 self.expect(TokenType::LBrace)?;
119 loop {
120 let token = self.peek_token();
121 if token.token_type == TokenType::RBrace {
122 break;
123 }
124
125 let (key, value) = self.parse_value()?;
126 object.insert(key, value);
127 let token = self.read_token();
128 match token.token_type {
129 TokenType::Comma => continue,
130 TokenType::RBrace => break,
131 _ => return Err(MapperError::UnexpectedToken(token)),
132 }
133 }
134 Ok(object)
135 }
136}
137
138#[cfg(test)]
139pub mod test {
140 use alloc::string::ToString;
141
142 #[test]
143 pub fn test_mapper() {
144 let input = r#"
145 {
146 "name": "John",
147 "age": 30,
148 "isActive": True,
149 "cars": [
150 {
151 "name": "Ford",
152 "plate": "20-13f"
153 },
154 {
155 "name": "Fiat",
156 "plate": "20-13f"
157 }
158 ]
159 }
160 "#
161 .to_string();
162
163 let token_list = crate::lexer::Lexer::new(input).tokenize().unwrap();
164 let mut mapper = crate::mapper::Mapper::new(token_list);
165 let object = mapper.parse_object().unwrap();
166 assert_eq!(object["name"].to_string(), "John");
167 assert_eq!(object["age"].to_string(), "30");
168 assert_eq!(object["isActive"].to_string(), "True");
169
170 let cars = match object["cars"] {
171 crate::mapper::Value::Array(ref cars) => cars,
172 _ => panic!("Expected array"),
173 };
174
175 let car1 = match cars[0] {
176 crate::mapper::Value::Object(ref car) => car,
177 _ => panic!("Expected object"),
178 };
179
180 let car2 = match cars[1] {
181 crate::mapper::Value::Object(ref car) => car,
182 _ => panic!("Expected object"),
183 };
184
185 assert_eq!(car1["name"].to_string(), "Ford");
186 assert_eq!(car1["plate"].to_string(), "20-13f");
187 assert_eq!(car2["name"].to_string(), "Fiat");
188 assert_eq!(car2["plate"].to_string(), "20-13f");
189 }
190}