1mod lexer;
2mod parser;
3pub mod json;
4
5#[cfg(test)]
6mod tests {
7 use std::{collections::HashMap, time};
8
9 use crate::json::{JSONValue, self, Cast};
10
11 use super::lexer::Lexer;
12
13 #[test]
14 fn lexer_test() {
15 let new_buf =
16 "
17{
18 \"foo\": \"bar\",
19 \"baz\": 134.0e-3,
20 \"beanz\": $ [false, true]
21}";
22 let mut lexer: Lexer = Lexer::new(new_buf.as_bytes().to_vec());
23
24 lexer.tokenify().expect_err("this should error");
25 }
26
27 #[test]
28 fn parser_test() -> json::Result<()> {
29 let buffer = std::fs::read("tests/array.json").unwrap();
30 assert_eq!(JSONValue::Array(vec![
31 JSONValue::Number(1.0),
32 JSONValue::Number(2.0),
33 JSONValue::Number(3.0),
34 JSONValue::Bool(true),
35 JSONValue::Null,
36 ]), JSONValue::try_from(buffer)?);
37
38 let buffer = std::fs::read("tests/string.json").unwrap();
39 let str: String = JSONValue::try_from(buffer)?.cast()?;
40 assert_eq!("asdfa sdfas\\df / wallalla tryn 165-08 {}{}___--=+123,./<>?".to_owned(), str);
41
42 Ok(())
43 }
44
45 macro_rules! int_test {
46 ($var:expr, $($type_name:ty)+) => {
47 $(let _var: $type_name = $var.cast()?;)+
48 };
49 }
50
51 #[test]
52 fn json_test() -> json::Result<()> {
53 let value = JSONValue::try_from(std::fs::read("tests/test.json").unwrap())?;
54
55 let a: String = value.get("foo")?.cast()?;
56 assert_eq!("bar", a);
57 let b: String = value["foo"].cast()?;
58 assert_eq!(a, b);
59
60 let bool: bool = value["baz"][0].cast()?;
61 assert_eq!(bool, true);
62 let bool_2: bool = value.get("baz")?.try_index(0)?.cast()?;
63 assert_eq!(bool, bool_2);
64
65 int_test!(value["obj"]["b"], i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32);
66 let the_answer: u8 = value["qux"]["qux_obj"]["nest_arr"][3]["the_answer"].cast()?;
67 assert_eq!(42, the_answer);
68
69 Ok(())
70 }
71
72 #[test]
73 fn serialize_test() -> json::Result<()> {
74 let mut values: JSONValue = JSONValue::Object(HashMap::new());
75 values.obj_insert("foo", JSONValue::from(vec![
76 JSONValue::from(23.4),
77 JSONValue::from("asdfasdf".to_owned()),
78 JSONValue::from(true),
79 ]))?;
80 values["foo"].arr_push(JSONValue::from(()))?;
81
82 let string = values.to_string();
83
84 assert_eq!("{
85 \"foo\": [
86 23.4,
87 \"asdfasdf\",
88 true,
89 null
90 ]
91}", format!("{string}"));
92
93 Ok(())
94 }
95
96 #[test]
97 fn big_parse_test() -> json::Result<()> {
98 let mut s: String = String::from("{");
99
100 for i in 0..2<<16 {
101 s.push_str(&format!("\"name_{0}\":{0},", i));
102 }
103
104 s.push_str(&format!("\"name_{0}\":{0}", 2<<16));
105 s.push('}');
106
107 let t0 = time::Instant::now();
108 let value = JSONValue::try_from(s.as_bytes().to_vec())?;
109 let t1 = time::Instant::now();
110
111 for i in 0..=2<<16 {
112 let v: i32 = value[format!("name_{}", i)].cast()?;
113 assert_eq!(i, v);
114 }
115 let t2 = time::Instant::now();
116 println!("time to complete parse: {}", (t1-t0).as_secs_f64());
117 println!("time to complete iteration: {}", (t2-t1).as_secs_f64());
118 println!("total time: {}", (t2-t0).as_secs_f64());
119
120 Ok(())
121 }
122}