Skip to content

Commit

Permalink
Don't store Strings inside FlatJson Values; use ranges into pretty-pr…
Browse files Browse the repository at this point in the history
…inted String instead.
  • Loading branch information
PaulJuliusMartinez committed Nov 7, 2021
1 parent 0502235 commit a226811
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 79 deletions.
28 changes: 14 additions & 14 deletions src/flatjson.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::fmt::Debug;
use std::ops::Range;

use serde_json::value::{Number, Value as SerdeValue};
use serde_json::value::Value as SerdeValue;

use crate::jsonparser;

Expand Down Expand Up @@ -50,7 +50,7 @@ pub struct FlatJson(
Vec<Row>,
// Single-line pretty printed version of the JSON.
// Rows will contain references into this.
String,
pub String,
// Max nesting depth.
usize,
);
Expand Down Expand Up @@ -257,9 +257,9 @@ impl ContainerType {
#[derive(Debug)]
pub enum Value {
Null,
Boolean(bool),
Number(Number),
String(String),
Boolean,
Number,
String,
EmptyObject,
EmptyArray,
OpenContainer {
Expand Down Expand Up @@ -410,24 +410,24 @@ fn flatten_json(serde_value: SerdeValue, flat_json: &mut Vec<Row>, parents: &mut
next_sibling: OptionIndex::Nil,
depth,
index: 0,
range: 0..0, // Not populated in when using Serde
range: 0..0, // Not populated in when using Serde
key_range: None, // Not populated in when using Serde
key: None,
value: Value::Null,
};

match serde_value {
SerdeValue::Null => flat_json.push(row),
SerdeValue::Bool(b) => flat_json.push(Row {
value: Value::Boolean(b),
SerdeValue::Bool(_) => flat_json.push(Row {
value: Value::Boolean,
..row
}),
SerdeValue::Number(n) => flat_json.push(Row {
value: Value::Number(n),
SerdeValue::Number(_) => flat_json.push(Row {
value: Value::Number,
..row
}),
SerdeValue::String(s) => flat_json.push(Row {
value: Value::String(s),
SerdeValue::String(_) => flat_json.push(Row {
value: Value::String,
..row
}),
SerdeValue::Array(vs) => {
Expand Down Expand Up @@ -479,7 +479,7 @@ fn flatten_json(serde_value: SerdeValue, flat_json: &mut Vec<Row>, parents: &mut
next_sibling: OptionIndex::Nil,
depth,
index: 0,
range: 0..0, // Not populated in when using Serde
range: 0..0, // Not populated in when using Serde
key_range: None, // Not populated in when using Serde
key: None,
value: Value::CloseContainer {
Expand Down Expand Up @@ -552,7 +552,7 @@ fn flatten_json(serde_value: SerdeValue, flat_json: &mut Vec<Row>, parents: &mut
next_sibling: OptionIndex::Nil,
depth,
index: 0,
range: 0..0, // Not populated in when using Serde
range: 0..0, // Not populated in when using Serde
key_range: None, // Not populated in when using Serde
key: None,
value: Value::CloseContainer {
Expand Down
10 changes: 3 additions & 7 deletions src/jsonparser.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use logos::{Lexer, Logos};
use serde_json::Number;

use crate::flatjson::{ContainerType, Index, OptionIndex, Row, Value};
use crate::jsontokenizer::JsonToken;
Expand Down Expand Up @@ -380,7 +379,7 @@ impl<'a> JsonParser<'a> {
fn parse_bool(&mut self, b: bool) -> Result<usize, String> {
self.advance();

let row_index = self.create_row(Value::Boolean(b));
let row_index = self.create_row(Value::Boolean);
let (bool_str, len) = if b { ("true", 4) } else { ("false", 5) };

self.rows[row_index].range.end = self.rows[row_index].range.start + len;
Expand All @@ -391,9 +390,7 @@ impl<'a> JsonParser<'a> {
}

fn parse_number(&mut self) -> Result<usize, String> {
let row_index = self.create_row(Value::Number(Number::from_string_unchecked(
self.tokenizer.slice().to_string(),
)));
let row_index = self.create_row(Value::Number);
self.pretty_printed.push_str(self.tokenizer.slice());

self.rows[row_index].range.end =
Expand All @@ -405,8 +402,7 @@ impl<'a> JsonParser<'a> {

fn parse_string(&mut self) -> Result<usize, String> {
let span_len = self.tokenizer.span().len();
let actual_str = &self.tokenizer.slice()[1..span_len - 1];
let row_index = self.create_row(Value::String(actual_str.to_string()));
let row_index = self.create_row(Value::String);

// The token includes the quotation marks.
self.pretty_printed.push_str(self.tokenizer.slice());
Expand Down
40 changes: 14 additions & 26 deletions src/lineprinter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,7 @@ impl<'a, TUI: TUIControl> LinePrinter<'a, TUI> {
quoted_object_keys,
)?
} else {
LinePrinter::<TUI>::fill_in_value_preview(buf, &row.value, available_space)?
LinePrinter::<TUI>::fill_in_value_preview(buf, &flatjson.1, &row, available_space)?
};
used_space += space_used_for_value;

Expand All @@ -753,37 +753,25 @@ impl<'a, TUI: TUIControl> LinePrinter<'a, TUI> {

fn fill_in_value_preview<W: Write>(
buf: &mut W,
value: &Value,
pretty_printed_json: &str,
row: &Row,
mut available_space: isize,
) -> Result<isize, fmt::Error> {
let number_value: String;
let mut quoted = false;
let mut can_be_truncated = true;

let mut value_ref = match value {
let mut value_ref = match &row.value {
Value::OpenContainer { container_type, .. } => {
can_be_truncated = false;
container_type.collapsed_preview()
}
Value::CloseContainer { .. } => panic!("CloseContainer cannot be child value."),
Value::Null => "null",
Value::Boolean(b) => {
if *b {
"true"
} else {
"false"
}
}
Value::Number(n) => {
number_value = n.to_string();
&number_value
}
Value::String(s) => {
Value::String => {
quoted = true;
s
let range = row.range.clone();
&pretty_printed_json[range.start + 1..range.end - 1]
}
Value::EmptyObject => "{}",
Value::EmptyArray => "[]",
_ => &pretty_printed_json[row.range.clone()],
};

let mut required_characters = min_required_columns_for_str(value_ref);
Expand Down Expand Up @@ -850,7 +838,7 @@ impl<'a, TUI: TUIControl> LinePrinter<'a, TUI> {
mod tests {
use unicode_width::UnicodeWidthStr;

use crate::flatjson::parse_top_level_json;
use crate::flatjson::parse_top_level_json2;
use crate::tuicontrol::test::{EmptyControl, VisibleEscapes};

use super::*;
Expand Down Expand Up @@ -923,7 +911,7 @@ mod tests {

#[test]
fn test_data_mode_focus_indicators() -> std::fmt::Result {
let mut fj = parse_top_level_json(OBJECT.to_owned()).unwrap();
let mut fj = parse_top_level_json2(OBJECT.to_owned()).unwrap();
let mut line: LinePrinter<'_, VisibleEscapes> = LinePrinter {
tui: VisibleEscapes::position_only(),
value: LineValue::Container {
Expand Down Expand Up @@ -1223,7 +1211,7 @@ mod tests {
// 01234567890123456789012345678901 (31 characters)
// {a: 1, d: {…}, "b c": null}
// 0123456789012345678901234567 (27 characters)
let fj = parse_top_level_json(json.to_owned()).unwrap();
let fj = parse_top_level_json2(json.to_owned()).unwrap();

for (available_space, used_space, quoted_object_keys, expected) in vec![
(50, 31, true, r#"{"a": 1, "d": {…}, "b c": null}"#),
Expand Down Expand Up @@ -1259,7 +1247,7 @@ mod tests {
let json = r#"[1, {"x": true}, null, "hello", true]"#;
// [1, {…}, null, "hello", true]
// 012345678901234567890123456789 (29 characters)
let fj = parse_top_level_json(json.to_owned()).unwrap();
let fj = parse_top_level_json2(json.to_owned()).unwrap();

for (available_space, used_space, expected) in vec![
(50, 29, r#"[1, {…}, null, "hello", true]"#),
Expand Down Expand Up @@ -1299,7 +1287,7 @@ mod tests {
let json = r#"{"a": [1, {"x": true}, null, "hello", true]}"#;
// {a: [1, {…}, null, "hello", true]}
// 01234567890123456789012345678901234 (34 characters)
let fj = parse_top_level_json(json.to_owned()).unwrap();
let fj = parse_top_level_json2(json.to_owned()).unwrap();

let (buf, used) = generate_container_preview(&fj, 34, false)?;
assert_eq!(r#"{a: [1, {…}, null, "hello", true]}"#, buf);
Expand All @@ -1312,7 +1300,7 @@ mod tests {
let json = r#"[{"a": 1, "d": {"x": true}, "b c": null}]"#;
// [{a: 1, d: {…}, "b c": null}]
// 012345678901234567890123456789 (29 characters)
let fj = parse_top_level_json(json.to_owned()).unwrap();
let fj = parse_top_level_json2(json.to_owned()).unwrap();

let (buf, used) = generate_container_preview(&fj, 29, false)?;
assert_eq!(r#"[{a: 1, d: {…}, "b c": null}]"#, buf);
Expand Down
51 changes: 19 additions & 32 deletions src/screenwriter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,39 +179,26 @@ impl ScreenWriter {
row,
}
}
Value::Null => lp::LineValue::Value {
s: "null",
quotes: false,
color: TUIColor::LightBlack,
},
Value::Boolean(b) => lp::LineValue::Value {
s: if *b { "true" } else { "false" },
quotes: false,
color: TUIColor::Yellow,
},
Value::Number(n) => {
number_value = n.to_string();
lp::LineValue::Value {
s: &number_value,
quotes: false,
color: TUIColor::Magenta,
}
_ => {
let color = match &row.value {
Value::Null => TUIColor::LightBlack,
Value::Boolean => TUIColor::Yellow,
Value::Number => TUIColor::Magenta,
Value::String => TUIColor::Green,
Value::EmptyObject => TUIColor::White,
Value::EmptyArray => TUIColor::White,
_ => TUIColor::White,
};

let range = row.range.clone();
let (s, quotes) = if let Value::String = &row.value {
(&viewer.flatjson.1[range.start + 1..range.end - 1], true)
} else {
(&viewer.flatjson.1[range], false)
};

lp::LineValue::Value { s, quotes, color }
}
Value::String(s) => lp::LineValue::Value {
s,
quotes: true,
color: TUIColor::Green,
},
Value::EmptyObject => lp::LineValue::Value {
s: "{}",
quotes: false,
color: TUIColor::White,
},
Value::EmptyArray => lp::LineValue::Value {
s: "[]",
quotes: false,
color: TUIColor::White,
},
};

let mut secondarily_focused = false;
Expand Down

0 comments on commit a226811

Please sign in to comment.