diff --git a/src/flatjson.rs b/src/flatjson.rs index e200c32..53b77f8 100644 --- a/src/flatjson.rs +++ b/src/flatjson.rs @@ -282,6 +282,7 @@ pub enum Value { Null, Boolean, Number, + NaN, String, EmptyObject, EmptyArray, diff --git a/src/jsonparser.rs b/src/jsonparser.rs index 9ccf937..8dd1fd7 100644 --- a/src/jsonparser.rs +++ b/src/jsonparser.rs @@ -120,6 +120,9 @@ impl<'a> JsonParser<'a> { JsonToken::Number => { return self.parse_number(); } + JsonToken::NaN => { + return self.parse_nan(); + } JsonToken::String => { return self.parse_string(); } @@ -399,6 +402,17 @@ impl<'a> JsonParser<'a> { Ok(row_index) } + fn parse_nan(&mut self) -> Result { + let row_index = self.create_row(Value::NaN); + self.pretty_printed.push_str(self.tokenizer.slice()); + + self.rows[row_index].range.end = + self.rows[row_index].range.start + self.tokenizer.slice().len(); + + self.advance(); + Ok(row_index) + } + fn parse_string(&mut self) -> Result { let row_index = self.create_row(Value::String); @@ -454,11 +468,11 @@ mod tests { #[test] fn test_row_ranges() { - // 0 2 7 10 15 21 26 32 39 42 - let json = r#"{ "a": 1, "b": true, "c": null, "ddd": [] }"#.to_owned(); + // 0 2 7 10 15 21 26 32 39 43 50 54 + let json = r#"{ "a": 1, "b": true, "c": null, "ddd": [], "val": NaN }"#.to_owned(); let (rows, _, _) = parse(json).unwrap(); - assert_eq!(rows[0].range, 0..43); // Object + assert_eq!(rows[0].range, 0..55); // Object assert_eq!(rows[1].key_range, Some(2..5)); // "a": 1 assert_eq!(rows[1].range, 7..8); // "a": 1 assert_eq!(rows[2].key_range, Some(10..13)); // "b": true @@ -466,7 +480,9 @@ mod tests { assert_eq!(rows[3].key_range, Some(21..24)); // "c": null assert_eq!(rows[3].range, 26..30); // "c": null assert_eq!(rows[4].range, 39..41); // "ddd": [] - assert_eq!(rows[5].range, 42..43); // } + assert_eq!(rows[5].key_range, Some(43..48)); // "val": NaN + assert_eq!(rows[5].range, 50..53); // "val": NaN + assert_eq!(rows[6].range, 54..55); // } // 01 5 14 21 23 let json = r#"[14, "apple", false, {}]"#.to_owned(); diff --git a/src/jsontokenizer.rs b/src/jsontokenizer.rs index e35e708..9db67e3 100644 --- a/src/jsontokenizer.rs +++ b/src/jsontokenizer.rs @@ -25,6 +25,9 @@ pub enum JsonToken { False, #[regex(r"-?(0|([1-9][0-9]*))(\.[0-9]+)?([eE][-+]?[0-9]+)?")] Number, + // Add support for some non-compliant but common not-a-numbers + #[regex(r"(NaN|Infinity|-Infinity)")] + NaN, // I get an error when I do [0-9a-fA-F]{4}. #[regex("\"((\\\\([\"\\\\/bfnrt]|u[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]))|[^\"\\\\\x00-\x1F])*\"")] String, diff --git a/src/screenwriter.rs b/src/screenwriter.rs index 7a5e0dd..307727a 100644 --- a/src/screenwriter.rs +++ b/src/screenwriter.rs @@ -220,6 +220,7 @@ impl ScreenWriter { _ => { let color = match &row.value { Value::Null => terminal::LIGHT_BLACK, + Value::NaN => terminal::LIGHT_RED, Value::Boolean => terminal::YELLOW, Value::Number => terminal::MAGENTA, Value::String => terminal::GREEN, diff --git a/src/terminal.rs b/src/terminal.rs index 32eec54..62d5e95 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -17,7 +17,7 @@ pub const MAGENTA: Color = Color::C16(5); // pub const CYAN: Color = Color::C16(6); pub const WHITE: Color = Color::C16(7); pub const LIGHT_BLACK: Color = Color::C16(8); -// pub const LIGHT_RED: Color = Color::C16(9); +pub const LIGHT_RED: Color = Color::C16(9); // pub const LIGHT_GREEN: Color = Color::C16(10); // pub const LIGHT_YELLOW: Color = Color::C16(11); pub const LIGHT_BLUE: Color = Color::C16(12);