Skip to main content

rust_web_server/json/array/
mod.rs

1//! JSON arrays: parse `[ … ]` into `Vec<T>` and back. For a struct type,
2//! implement [`New`](crate::core::New), [`FromJSON`](crate::json::object::FromJSON) and
3//! [`ToJSON`](crate::json::object::ToJSON), then call `from_json_list` / `to_json_list`.
4//! Scalar arrays (integers, floats, strings, booleans, nulls) have their own
5//! helpers in the submodules.
6
7use std::io;
8use std::io::Read;
9use crate::symbol::SYMBOL;
10
11#[cfg(test)]
12mod tests;
13
14pub mod boolean;
15pub mod string;
16pub mod null;
17pub mod float;
18pub mod integer;
19pub mod object;
20
21pub struct RawUnprocessedJSONArray;
22impl RawUnprocessedJSONArray {
23    pub fn split_into_vector_of_strings(_json_string: String) -> Result<Vec<String>, String> {
24        let mut list : Vec<String> = vec![];
25
26        // cursor
27        let mut is_end_of_json_string = false;
28        let mut cursor = io::Cursor::new(_json_string.to_string());
29        let mut bytes_read : i128 = 0;
30        let total_bytes : i128 = _json_string.len() as i128;
31
32
33        // read the start of the array
34
35        let mut read_until_start_of_array = true;
36        while read_until_start_of_array {
37
38            if is_end_of_json_string {
39                let message = format!("not proper end of the json array: {}", _json_string.to_string());
40                return Err(message);
41            }
42
43            let byte = 0;
44            let mut char_buffer = vec![byte];
45            let length = char_buffer.len();
46            let boxed_read = cursor.read_exact(&mut char_buffer);
47            if boxed_read.is_err() {
48                let message = boxed_read.err().unwrap().to_string();
49                return Err(message);
50            }
51            boxed_read.unwrap();
52            bytes_read = bytes_read + length as i128;
53            is_end_of_json_string = total_bytes == bytes_read;
54            if is_end_of_json_string {
55                let message = format!("not proper start of the json array: {}", _json_string.to_string());
56                return Err(message);
57            }
58            let char = String::from_utf8(char_buffer).unwrap().chars().last().unwrap();
59
60            if !char.is_whitespace() && char != '['{
61                let message = format!("input string does not start with opening square bracket: {} in {}", char, _json_string);
62                return Err(message);
63            }
64
65            if char == '[' {
66                read_until_start_of_array = false;
67            }
68        }
69
70
71
72        let mut is_end_of_array = false;
73        let mut token;
74        while !is_end_of_array {
75
76            let byte = 0;
77            let mut char_buffer = vec![byte];
78            let length = char_buffer.len();
79            let boxed_read = cursor.read_exact(&mut char_buffer);
80            if boxed_read.is_err() {
81                let message = boxed_read.err().unwrap().to_string();
82                return Err(message);
83            }
84            boxed_read.unwrap();
85            bytes_read = bytes_read + length as i128;
86            let mut char = String::from_utf8(char_buffer).unwrap().chars().last().unwrap();
87
88            if char == ']' {
89                is_end_of_array = true;
90            }
91
92            if char != ' ' && char != ']' {
93                let is_string = char == '\"';
94                if is_string {
95                    token = ["".to_string(), char.to_string()].join(SYMBOL.empty_string);
96
97                    // read till non escaped '"'
98                    let mut not_end_of_string_property_value = true;
99                    while not_end_of_string_property_value {
100                        let byte = 0;
101                        char_buffer = vec![byte];
102                        let boxed_read = cursor.read_exact(&mut char_buffer);
103                        if boxed_read.is_err() {
104                            let message = boxed_read.err().unwrap().to_string();
105                            return Err(message);
106                        }
107                        boxed_read.unwrap();
108                        let length = char_buffer.len();
109                        bytes_read = bytes_read + length as i128;
110                        let _char = String::from_utf8(char_buffer).unwrap();
111                        let last_char_in_buffer = token.chars().last().unwrap().to_string();
112                        not_end_of_string_property_value = _char != "\"" && last_char_in_buffer != "\\";
113                        token = [token, _char.to_string()].join(SYMBOL.empty_string);
114                    }
115                    list.push(token.to_string());
116
117                    // if char is whitespace read until non whitespace and check it is comma, if not return error
118                    let is_whitespace = char == ' ';
119                    if is_whitespace {
120                        let mut read_till_end_of_whitespace = true;
121                        while read_till_end_of_whitespace {
122                            let byte = 0;
123                            let mut char_buffer = vec![byte];
124                            let length = char_buffer.len();
125                            let boxed_read = cursor.read_exact(&mut char_buffer);
126                            if boxed_read.is_err() {
127                                let message = boxed_read.err().unwrap().to_string();
128                                return Err(message);
129                            }
130                            boxed_read.unwrap();
131                            bytes_read = bytes_read + length as i128;
132                            char = String::from_utf8(char_buffer).unwrap().chars().last().unwrap();
133
134                            if char == ',' {
135                                read_till_end_of_whitespace = false
136                            } else {
137                                if char == ']' {
138                                    read_till_end_of_whitespace = false;
139                                    is_end_of_array = true;
140                                } else {
141                                    let message = format!("Missing comma between array items or closing square bracket at the end of array: {}", _json_string);
142                                    return Err(message);
143                                }
144                            }
145                        }
146                    }
147                }
148
149                let is_null = char == 'n';
150                if is_null {
151                    // read 'ull'
152                    token = ["".to_string(), char.to_string()].join(SYMBOL.empty_string);
153                    let byte = 0;
154                    let mut char_buffer = vec![byte, byte, byte];
155                    let length = char_buffer.len();
156                    let boxed_read = cursor.read_exact(&mut char_buffer);
157                    if boxed_read.is_err() {
158                        let message = boxed_read.err().unwrap().to_string();
159                        return Err(message);
160                    }
161                    boxed_read.unwrap();
162                    bytes_read = bytes_read + length as i128;
163                    let remaining_bool = String::from_utf8(char_buffer).unwrap();
164                    if remaining_bool != "ull" {
165                        let message = format!("Unable to parse null: {} in {}", remaining_bool, _json_string);
166                        return Err(message)
167                    }
168                    token = [token.to_string(), remaining_bool.to_string()].join(SYMBOL.empty_string);
169                    list.push(token.to_string());
170                }
171
172                let is_boolean_true = char == 't';
173                if is_boolean_true {
174                    // read 'rue'
175                    token = ["".to_string(), char.to_string()].join(SYMBOL.empty_string);
176                    let byte = 0;
177                    let mut char_buffer = vec![byte, byte, byte];
178                    let length = char_buffer.len();
179                    let boxed_read = cursor.read_exact(&mut char_buffer);
180                    if boxed_read.is_err() {
181                        let message = boxed_read.err().unwrap().to_string();
182                        return Err(message);
183                    }
184                    boxed_read.unwrap();
185                    bytes_read = bytes_read + length as i128;
186                    let remaining_bool = String::from_utf8(char_buffer).unwrap();
187                    if remaining_bool != "rue" {
188                        let message = format!("Unable to parse true: {} in {}", remaining_bool, _json_string);
189                        return Err(message)
190                    }
191                    token = [token.to_string(), remaining_bool.to_string()].join(SYMBOL.empty_string);
192                    list.push(token.to_string());
193                }
194
195                let is_boolean_false = char == 'f';
196                if is_boolean_false {
197                    // read 'alse'
198                    token = ["".to_string(), char.to_string()].join(SYMBOL.empty_string);
199                    let byte = 0;
200                    let mut char_buffer = vec![byte, byte, byte, byte];
201                    let length = char_buffer.len();
202                    let boxed_read = cursor.read_exact(&mut char_buffer);
203                    if boxed_read.is_err() {
204                        let message = boxed_read.err().unwrap().to_string();
205                        return Err(message);
206                    }
207                    boxed_read.unwrap();
208                    bytes_read = bytes_read + length as i128;
209                    let remaining_bool = String::from_utf8(char_buffer).unwrap();
210                    if remaining_bool != "alse" {
211                        let message = format!("Unable to parse false: {} in {}", remaining_bool, _json_string);
212                        return Err(message)
213                    }
214                    token = [token.to_string(), remaining_bool.to_string()].join(SYMBOL.empty_string);
215                    list.push(token.to_string());
216                }
217
218                let is_array = char == '[';
219                if is_array {
220                    // read the array (including nested objects and arrays)
221                    token = ["".to_string(), char.to_string()].join(SYMBOL.empty_string);
222                    let mut number_of_open_square_brackets = 1;
223                    let mut number_of_closed_square_brackets = 0;
224
225                    let mut read_nested_array = true;
226                    while read_nested_array {
227
228                        let byte = 0;
229                        let mut char_buffer = vec![byte];
230                        let length = char_buffer.len();
231                        let boxed_read = cursor.read_exact(&mut char_buffer);
232                        if boxed_read.is_err() {
233                            let message = boxed_read.err().unwrap().to_string();
234                            return Err(message);
235                        }
236                        boxed_read.unwrap();
237                        bytes_read = bytes_read + length as i128;
238                        let char = String::from_utf8(char_buffer).unwrap().chars().last().unwrap();
239
240                        let is_open_square_bracket = char == '[';
241                        if is_open_square_bracket {
242                            number_of_open_square_brackets = number_of_open_square_brackets + 1;
243                        }
244
245
246                        let is_close_square_bracket = char == ']';
247                        if is_close_square_bracket {
248                            number_of_closed_square_brackets = number_of_closed_square_brackets + 1;
249                        }
250
251                        token = [token.to_string(), char.to_string()].join(SYMBOL.empty_string);
252
253                        if number_of_open_square_brackets == number_of_closed_square_brackets {
254                            list.push(token.to_string());
255                            read_nested_array = false;
256                        }
257                    }
258                }
259
260
261                let is_nested_object = char == '{';
262                if is_nested_object {
263                    // read the object (including nested objects and arrays)
264                    token = ["".to_string(), char.to_string()].join(SYMBOL.empty_string);
265                    let mut number_of_open_curly_braces = 1;
266                    let mut number_of_closed_curly_braces = 0;
267
268                    let mut read_nested_object = true;
269                    while read_nested_object {
270
271                        let byte = 0;
272                        let mut char_buffer = vec![byte];
273                        let length = char_buffer.len();
274                        let boxed_read = cursor.read_exact(&mut char_buffer);
275                        if boxed_read.is_err() {
276                            let message = boxed_read.err().unwrap().to_string();
277                            return Err(message);
278                        }
279                        boxed_read.unwrap();
280                        bytes_read = bytes_read + length as i128;
281                        let char = String::from_utf8(char_buffer).unwrap().chars().last().unwrap();
282
283                        let is_open_curly_brace = char == '{';
284                        if is_open_curly_brace {
285                            number_of_open_curly_braces = number_of_open_curly_braces + 1;
286                        }
287
288
289                        let is_close_curly_brace = char == '}';
290                        if is_close_curly_brace {
291                            number_of_closed_curly_braces = number_of_closed_curly_braces + 1;
292                        }
293
294                        token = [token.to_string(), char.to_string()].join(SYMBOL.empty_string);
295
296                        if number_of_open_curly_braces == number_of_closed_curly_braces {
297                            list.push(token.to_string());
298                            read_nested_object = false;
299                        }
300                    }
301                }
302
303                let mut is_comma_separator = char == ',';
304                let is_numeric = char.is_numeric();
305                let is_minus = char == '-';
306
307                let is_number =
308                    !is_string &&
309                        !is_null &&
310                        !is_boolean_true &&
311                        !is_boolean_false &&
312                        !is_array &&
313                        !is_nested_object &&
314                        !is_comma_separator &&
315                        (is_numeric || is_minus);
316                if is_number {
317                    token = "".to_string();
318                    // read until char is not number and decimal point, minus, exponent
319                    if char != ',' {
320                        token = ["".to_string(), char.to_string()].join(SYMBOL.empty_string);
321                    }
322
323                    let mut _is_point_symbol_already_used = false;
324                    let mut _is_exponent_symbol_already_used = false;
325                    let mut _is_minus_symbol_already_used = false;
326                    if char == '-' {
327                        _is_minus_symbol_already_used = true;
328                    }
329
330                    let mut read_number = true;
331                    while read_number {
332
333                        let byte = 0;
334                        let mut char_buffer = vec![byte];
335                        let length = char_buffer.len();
336                        let boxed_read = cursor.read_exact(&mut char_buffer);
337                        if boxed_read.is_err() {
338                            let message = boxed_read.err().unwrap().to_string();
339                            return Err(message);
340                        }
341                        boxed_read.unwrap();
342                        bytes_read = bytes_read + length as i128;
343                        char = String::from_utf8(char_buffer).unwrap().chars().last().unwrap();
344
345                        let is_numeric = char.is_numeric();
346
347                        let is_point_symbol = char == '.';
348                        if is_point_symbol && _is_point_symbol_already_used {
349                            _is_point_symbol_already_used = true;
350                            let message = format!("unable to parse number: {} in {}", token, _json_string);
351                            return Err(message)
352                        }
353                        if is_point_symbol {
354                            _is_point_symbol_already_used = true;
355                        }
356
357                        let is_exponent_symbol = char == 'e';
358                        if is_exponent_symbol && _is_exponent_symbol_already_used {
359                            _is_exponent_symbol_already_used = true;
360                            let message = format!("unable to parse number: {} in {}", token, _json_string);
361                            return Err(message)
362                        }
363                        if is_exponent_symbol {
364                            _is_exponent_symbol_already_used = true;
365                        }
366
367                        let is_minus_symbol = char == '-';
368                        if is_minus_symbol && _is_minus_symbol_already_used {
369                            _is_minus_symbol_already_used = true;
370                            let message = format!("unable to parse number: {} in {}", token, _json_string);
371                            return Err(message)
372                        }
373
374                        let char_is_part_of_number = is_numeric || is_point_symbol || is_exponent_symbol || is_minus_symbol;
375                        // if char is whitespace read until non whitespace and check it is comma, if not return error
376                        let is_whitespace = char == ' ';
377                        if is_whitespace {
378                            let mut read_till_end_of_whitespace = true;
379                            while read_till_end_of_whitespace {
380                                let byte = 0;
381                                let mut char_buffer = vec![byte];
382                                let length = char_buffer.len();
383                                let boxed_read = cursor.read_exact(&mut char_buffer);
384                                if boxed_read.is_err() {
385                                    let message = boxed_read.err().unwrap().to_string();
386                                    return Err(message);
387                                }
388                                boxed_read.unwrap();
389                                bytes_read = bytes_read + length as i128;
390                                char = String::from_utf8(char_buffer).unwrap().chars().last().unwrap();
391
392                                if char == ',' {
393                                    read_till_end_of_whitespace = false
394                                } else {
395                                    if char == ']' {
396                                        read_till_end_of_whitespace = false;
397                                        is_end_of_array = true;
398                                    } else {
399                                        let message = format!("Missing comma between array items or closing square bracket at the end of array: {}", _json_string);
400                                        return Err(message);
401                                    }
402                                }
403                            }
404                        }
405
406                        if char_is_part_of_number {
407                            token = [token, char.to_string()].join(SYMBOL.empty_string);
408                        } else {
409                            read_number = false;
410                            // if char is not array element separator or end of the array
411                            if char != ',' && char != ']' {
412                                let message = format!("unable to parse number: {} in {}", char, _json_string);
413                                return Err(message)
414                            }
415
416                        }
417                    }
418                    list.push(token.to_string());
419                }
420
421                is_comma_separator = char == ',';
422                let is_ascii_control = char.is_ascii_control();
423                let is_carriage_return = char == '\r';
424                let is_newline = char == '\n';
425                let is_not_supported_type =
426                    !is_string &&
427                        !is_null &&
428                        !is_boolean_true &&
429                        !is_boolean_false &&
430                        !is_array &&
431                        !is_nested_object &&
432                        !is_comma_separator &&
433                        !is_carriage_return &&
434                        !is_newline &&
435                        !is_ascii_control &&
436                        !is_numeric;
437                if is_not_supported_type {
438                    let message = format!("unknown type: {} in {}", char, _json_string);
439                    return Err(message);
440                }
441
442            }
443
444
445            if !is_end_of_array {
446                is_end_of_array = char == ']';
447            }
448
449        }
450
451
452        is_end_of_json_string = total_bytes == bytes_read;
453        let mut read_after_end_of_array = !is_end_of_json_string;
454        while read_after_end_of_array {
455
456            let byte = 0;
457            let mut char_buffer = vec![byte];
458            let length = char_buffer.len();
459            let boxed_read = cursor.read_exact(&mut char_buffer);
460            if boxed_read.is_err() {
461                let message = boxed_read.err().unwrap().to_string();
462                return Err(message);
463            }
464            boxed_read.unwrap();
465            bytes_read = bytes_read + length as i128;
466            let char = String::from_utf8(char_buffer).unwrap().chars().last().unwrap();
467
468            if !char.is_whitespace(){
469                let message = format!("after array there are some characters: {} in {}", char, _json_string);
470                return Err(message);
471            }
472
473            if bytes_read == total_bytes {
474                read_after_end_of_array = false;
475            }
476        }
477
478        Ok(list)
479    }
480}
481
482
483
484
485
486
487
488
489
490
491