1#![allow(non_snake_case, unused_assignments)]
74
75use std::{fs, path};
76use std::collections::HashSet;
77
78const DIGITS: [&str; 11] = [
79 "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "."
80];
81
82#[derive(Debug, PartialEq)]
83enum Token {
84 String(String),
85 Int(usize),
86 Float(f32),
87 OpenBrace,
88 CloseBrace,
89 OpenBracket,
90 CloseBracket,
91 Colon,
92 Comma,
93 Bool(bool),
94 Null
95}
96
97impl Token {
98 fn toString(&self) -> String {
99 match self {
100 Token::String(string) => string.clone(),
101 _ => String::new()
102 }
103 }
104}
105
106struct Parser {
107 tokens: Vec<Token>,
108 index: usize,
109 text: String ,
110 len: usize
111}
112
113impl Parser {
114 fn new(text: String) -> Parser {
115 return Parser {
116 tokens: Vec::<Token>::new(),
117 index: 0_usize,
118 len: (&text).len(),
119 text: text
120 }
121 }
122
123 fn get(&mut self) -> String {
124 match self.text.get(self.index..self.index+1) {
125 Some(c) => c.to_string(),
126 None => {
127 panic!("Non utf8 character found, which is not accepted")
128 }
129 }
130 }
131
132 fn checkNotEnd(&self) -> bool {
133 self.index != self.len
134 }
135
136 fn parse(&mut self) -> bool {
137 self.skipNull();
138 while self.checkNotEnd() {
139 let mut current = self.get();
140
141 if current == "\"" {
142 self.index += 1;
143
144 let mut value = String::new();
145
146 while self.checkNotEnd() {
147 current = self.get();
148
149 if current.as_str() == "\"" && (&self.text[self.index-1..self.index] != "\\") {
150 break
151
152 } else if current.as_str() == "\"" && (&self.text[self.index-1..self.index] == "\\" && &self.text[self.index-2..self.index-1] == "\\") {
153 break
154 }
155
156 value += current.as_str();
157 self.index += 1;
158 }
159
160 if ! self.checkNotEnd() {
161 return true;
162 }
163 self.index += 1;
164
165 self.tokens.push(Token::String(value));
166
167 } else if self.get() == ":" {
168 self.tokens.push(Token::Colon);
169 self.index += 1;
170
171 } else if self.get() == "," {
172 self.tokens.push(Token::Comma);
173 self.index += 1;
174
175 } else if self.get() == "{" {
176 self.tokens.push(Token::OpenBrace);
177 self.index += 1;
178
179 } else if self.get() == "}" {
180 self.tokens.push(Token::CloseBrace);
181 self.index += 1;
182
183 } else if self.get() == "[" {
184 self.tokens.push(Token::OpenBracket);
185 self.index += 1;
186
187 } else if self.get() == "]" {
188 self.tokens.push(Token::CloseBracket);
189 self.index += 1;
190
191 } else if DIGITS.contains(&self.get().as_str()) {
192 let mut value = String::new();
193
194 while self.checkNotEnd() && DIGITS.contains(&self.get().as_str()) {
195 value += self.get().as_str();
196 self.index += 1;
197 }
198
199 if ! self.checkNotEnd() {
200 return true;
201 }
202
203 if value.contains(".") {
204 self.tokens.push(Token::Float(value.parse::<f32>().unwrap()))
205
206 } else {
207 self.tokens.push(Token::Int(value.parse::<usize>().unwrap()))
208 }
209
210 } else if self.get() == "t" || self.get() == "f" || self.get() == "n" {
211 if self.len - self.index - 4 > 0 && &self.text[self.index..self.index + 4] == "true" {
212 self.tokens.push(Token::Bool(true));
213 self.index += 4;
214
215 } else if self.len - self.index - 4 > 0 && &self.text[self.index..self.index + 4] == "null" {
216 self.tokens.push(Token::Null);
217 self.index += 4;
218
219 } else if self.len - self.index - 5 > 0 && &self.text[self.index..self.index + 5] == "false" {
220 self.tokens.push(Token::Bool(false));
221 self.index += 5;
222
223 } else {
224 return true
225 }
226 }
227 self.skipNull();
228 }
229
230 false
231 }
232
233 fn skipNull(&mut self) {
234 let skip = [" ", "\t", "\n"];
235
236 while self.index < self.len && skip.contains(&&self.text[self.index..self.index + 1]) {
237 self.index += 1;
238 }
239 }
240}
241
242#[derive(Debug, Clone, PartialEq)]
243pub enum NodeContent {
244 String(String),
245 Int(usize),
246 Float(f32),
247 Bool(bool),
248 List(Vec<NodeContent>),
249 Json(Json),
250 Null
251}
252
253impl NodeContent {
254 pub fn toString(&self) -> Option<String> {
255 match self {
256 NodeContent::String(value) => Some(value.to_string().replace("\"", "\\\"")),
257 _ => None
258 }
259 }
260
261 pub fn toUsize(&self) -> Option<usize> {
262 match self {
263 NodeContent::Int(value) => Some(value.to_owned()),
264 _ => None
265 }
266 }
267
268 pub fn toBool(&self) -> Option<bool> {
269 match self {
270 NodeContent::Bool(value) => Some(value.to_owned()),
271 _ => None
272 }
273 }
274
275 pub fn toFloat(&self) -> Option<f32> {
276 match self {
277 NodeContent::Float(value) => Some(value.to_owned()),
278 _ => None
279 }
280 }
281
282 pub fn toJson(&self) -> Option<Json> {
283 match self {
284 NodeContent::Json(value) => Some(value.clone()),
285 _ => None
286 }
287 }
288
289 pub fn toList(&self) -> Option<Vec<NodeContent>> {
290 match self {
291 NodeContent::List(value) => Some(value.clone()),
292 _ => None
293 }
294 }
295
296 pub fn toNull(&self) -> Option<Node> {
297 return None;
298 }
299}
300
301#[derive(Debug, Clone, PartialEq)]
304pub struct Node {
305 label: String,
306 content: NodeContent
307}
308
309impl Node {
310 pub fn new<T: ToString>(label: T, content: NodeContent) -> Node {
311 Node {
312 label: label.to_string().replace("\"", "\\\""),
313 content: content
314 }
315 }
316
317 pub fn getLabel(&self) -> String {
318 return self.label.clone();
319 }
320
321 pub fn getContent(&self) -> NodeContent {
322 return self.content.clone();
323 }
324}
325
326#[derive(Debug, Clone, PartialEq)]
327pub struct Json {
328 nodes: Vec<Node>,
329 labels: HashSet<String>
330}
331
332impl Json {
333 pub fn new() -> Json {
334 return Json {
335 nodes: Vec::<Node>::new(),
336 labels: HashSet::<String>::new()
337 }
338 }
339
340 pub fn fromFile<T: ToString>(filePath: T) -> Result<Json, String> {
342 match std::fs::read_to_string(filePath.to_string()) {
343 Err(why) => Err(format!("Failed because: {why}")),
344 Ok(content) => Json::fromString(content)
345 }
346 }
347
348 pub fn fromString<T: ToString>(text: T) -> Result<Json, String> {
349 let mut parser = Parser::new(text.to_string());
350 let error = parser.parse();
351
352 if error {
353 return Err(String::from("Json format error"));
354 }
355
356 let tokens = parser.tokens;
357
358 if tokens.get(0).unwrap() != &Token::OpenBrace {
359 return Err(String::from("Json format error: missing opening curly bracket"));
360 }
361
362 let index = 1_usize;
363
364 let (_, json, error) = Self::json(&tokens, index);
365 if error {
366 return Err(String::from("Json format error"));
367 }
368
369 return Ok(json.unwrap())
370 }
371
372 fn json(tokens: &Vec<Token>, startIndex: usize) -> (usize, Option<Json>, bool) {
373 let mut index = startIndex;
374 let mut nodes = Vec::<Node>::new();
375 let mut labels = HashSet::<String>::new();
376
377 while index < tokens.len() {
378 match tokens.get(index).unwrap() {
379 Token::String(_) => {
380 let (newIndex, node, error) = Self::node(&tokens, index);
381
382 if error {
383 return (index, None, true)
384 }
385
386 index = newIndex;
387 if tokens.get(index).unwrap() != &Token::CloseBrace && tokens.get(index).unwrap() != &Token::Comma {
388 return (index, None, true)
389
390 } else if tokens.get(index).unwrap() == &Token::Comma {
391 index += 1;
392 }
393
394 match node {
395 Some(node) => {
396 labels.insert(node.label.clone());
397 nodes.push(node);
398 },
399 None => {}
400 }
401 },
402 Token::CloseBrace => {
403 break
404 }
405 _ => return (index, None, true)
406 }
407 }
408 (index, Some(Json{nodes: nodes, labels}), false)
409 }
410
411 fn list(tokens: &Vec<Token>, startIndex: usize) -> (usize, Option<NodeContent>, bool) {
412 let mut index = startIndex;
413 let mut content = Vec::<NodeContent>::new();
414
415 while tokens.get(index).unwrap() != &Token::CloseBracket {
416 match tokens.get(index).unwrap() {
417 Token::String(string) => {
418 content.push(NodeContent::String(string.to_owned()));
419 index += 1;
420 },
421
422 Token::Int(int) => {
423 content.push(NodeContent::Int(int.to_owned()));
424 index += 1;
425 },
426
427 Token::Float(float) => {
428 content.push(NodeContent::Float(float.to_owned()));
429 index += 1;
430 },
431
432 Token::Null => {
433 content.push(NodeContent::Null);
434 index += 1;
435 },
436
437 Token::Bool(bool) => {
438 content.push(NodeContent::Bool(bool.to_owned()));
439 index += 1;
440 },
441
442 Token::OpenBrace => {
443 let (newIndex, json, error) = Self::json(tokens, index + 1);
444
445 if error {
446 return (index, None, true)
447 }
448
449 index = newIndex + 1;
450 content.push(NodeContent::Json(json.unwrap()));
451 },
452
453 Token::OpenBracket => {
454 let (newIndex, list, error) = Self::list(tokens, index);
455
456 if error {
457 return (index, None, true)
458 }
459
460 index = newIndex;
461 content.push(list.unwrap())
462 },
463
464 Token::Comma => {
465 index += 1;
466 },
467
468 _ => {
469 return (index, None, true)
470 }
471
472
473 }
474 }
475 if tokens.get(index-1).unwrap() == &Token::Comma {
476 return (index, None, true);
477 }
478
479 (index, Some(NodeContent::List(content)), false)
480 }
481
482 fn node(tokens: &Vec<Token>, startIndex: usize) -> (usize, Option<Node>, bool) {
483 let mut index = startIndex;
484 let label = tokens.get(index).unwrap().toString();
485
486 index += 1;
487 if tokens.get(index).unwrap() != &Token::Colon {
488 return (index, None, true)
489 }
490 index += 1;
491
492 let mut content = NodeContent::Null;
493 match tokens.get(index).unwrap() {
494 Token::Null => {
495 content = NodeContent::Null;
496 index += 1;
497 },
498
499 Token::Int(int) => {
500 content = NodeContent::Int(int.to_owned());
501 index += 1;
502 },
503
504 Token::Float(float) => {
505 content = NodeContent::Float(float.to_owned());
506 index += 1;
507 },
508
509 Token::Bool(bool) => {
510 content = NodeContent::Bool(bool.to_owned());
511 index += 1;
512 },
513
514 Token::String(string) => {
515 content = NodeContent::String(string.to_owned());
516 index += 1;
517 },
518
519 Token::OpenBrace => {
520 index += 1;
521 let (newIndex, nodeContent, error) = Self::json(tokens, index);
522 if error {
523 return (index, None, true)
524 }
525 index = newIndex + 1;
526 content = NodeContent::Json(nodeContent.unwrap());
527 },
528
529 Token::OpenBracket => {
530 index += 1;
531 let (newIndex, list, error) = Self::list(tokens, index);
532
533 if error {
534 return (index, None, true);
535 }
536
537 index = newIndex + 1;
538 content = list.unwrap();
539 }
540
541 _ => {
542 return (index, None, true)
543 }
544 }
545
546 (index, Some(Node{label: label, content: content}), false)
547 }
548
549 pub fn getAllNodes(&self) -> Vec<Node> {
551 return self.nodes.clone();
552 }
553
554 pub fn get<T: ToString>(&self, label: T) -> Option<&NodeContent> {
556 for node in &self.nodes {
557 if node.label == label.to_string() {
558 return Some(&node.content)
559 }
560 }
561
562 return None;
563 }
564
565 pub fn getNode<T: ToString>(&self, label: T) -> Option<&Node> {
567 for node in &self.nodes {
568 if node.label == label.to_string() {
569 return Some(node);
570 }
571 }
572 return None;
573 }
574
575 fn renderJson(json: &Json) -> String {
576 let mut content = String::from("{");
577
578 for node in &json.nodes {
579 let mut label = (&node.label).to_owned();
580 label = label.replace("\\", "\\\\").replace("\"", "\\\"");
581
582 content = format!("{}\"{}\":{},", content, &node.label, Self::renderContent(&node.content));
583 }
584
585 if content.len() > 2 {
586 format!("{}{}", content[0..content.len()-1].to_string(), "}")
587
588 } else {
589 format!("{}{}", content, "}")
590 }
591 }
592
593 fn renderList(list: &Vec<NodeContent>, ) -> String {
594 let mut content = String::from("[");
595
596 for node in list {
597 content = format!("{}{},", content, Self::renderContent(&node))
598 }
599
600 if content.len() > 1 {
601 format!("{}{}", content[0..content.len()-1].to_string(), "]")
602 } else {
603 String::from("[]")
604 }
605 }
606
607 pub fn renderContent(object: &NodeContent) -> String {
608 match object {
609 NodeContent::Bool(bool) => if *bool { String::from("true") } else { String::from("false") },
610 NodeContent::Float(float) => format!("{}", float),
611 NodeContent::Int(int) => format!("{}", int),
612 NodeContent::Null => String::from("null"),
613 NodeContent::String(string) => format!("\"{}\"", string.replace("\\", "\\\\").replace("\"", "\\\"")),
614 NodeContent::List(list) => Self::renderList(&list),
615 NodeContent::Json(json) => Self::renderJson(&json),
616 }
617 }
618
619 pub fn writeToFile<T: ToString>(&self, fileName: T) -> bool {
621 let content = Json::renderJson(self);
622
623 return match fs::write(path::Path::new(&fileName.to_string()), content) {
624 Err(_) => false,
625 Ok(_) => true
626 }
627 }
628
629 pub fn toString(&self) -> String {
631 return Json::renderJson(self);
632 }
633
634 pub fn addNode(&mut self, node: Node) {
636 self.nodes.push(node);
637 }
638
639 pub fn setContent<T: ToString>(&mut self, label: T, content: NodeContent) -> bool {
641 for node in &mut self.nodes {
642 if node.label == label.to_string() {
643
644 node.content = content;
645 return true;
646 }
647 }
648
649 return false;
650 }
651
652 pub fn remove<T: ToString>(&mut self, label: T) -> bool {
654 let mut index: usize = 0;
655
656 for node in &self.nodes {
657 if node.label == label.to_string() {
658 self.nodes.remove(index);
659
660 return true;
661 }
662 index += 1;
663 }
664 return false;
665 }
666
667 pub fn bytes(&self) -> Vec<u8> {
669 Json::renderJson(self).bytes().collect::<Vec<u8>>()
670 }
671
672 pub fn has<T: ToString>(&self, label: T) -> bool{
674 self.labels.contains(&label.to_string())
675 }
676}
677
678#[macro_export]
679macro_rules! json {
680 ( $string:expr ) => {
681 Json::fromString($string)
682 };
683}
684
685#[cfg(test)]
686mod tests {
687 use super::*;
688
689 #[test]
690 fn test() {
691 let content = std::fs::read_to_string("./map.json");
692 let j = Json::fromString(content.unwrap()).unwrap();
693
694 println!("{:?}", j);
695 return;
696 }
697}