Skip to content

Commit

Permalink
pretty print
Browse files Browse the repository at this point in the history
  • Loading branch information
tinaxd committed Dec 9, 2019
1 parent aee3f14 commit e97bfc6
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 2 deletions.
98 changes: 98 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,102 @@ pub fn minimize_json(json: &str) -> String {
}
}
result
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum JsonContext {
Object, Array, String,
}

pub fn pretty_json(json: &str, setting: &PrettySetting) -> String {
let compressed = minimize_json(json);
let dirty = &compressed;

let mut curr_indentlv = 0;
let mut result = String::new();
let mut ctx: Vec<JsonContext> = vec![JsonContext::Object]; // Used as stack
let mut skip_char = false;
let mut last_comma = false;

for ch in dirty.chars() {
if skip_char {
skip_char = false;
result.push(ch);
last_comma = false;
continue;
}

if ctx[0] == JsonContext::String {
if ch == '\\' {
skip_char = true;
} else if ch == '\"' {
ctx.pop();
}
result.push(ch);
last_comma = false;
continue;
}

if ch == '\"' {
result.push(ch);
ctx.push(JsonContext::String);
last_comma = false;
continue;
}

if ch == ',' {
result.push(ch);
result.push('\n');
for _ in 0..(curr_indentlv * setting.indent_width) {
result.push(' ');
}
last_comma = true;
continue;
}

if ch == '[' || ch == '{' {
result.push(ch);
result.push('\n');
curr_indentlv += 1;
for _ in 0..(curr_indentlv * setting.indent_width) {
result.push(' ');
}
ctx.push(match ch {
'[' => JsonContext::Array,
'{' => JsonContext::Object,
_ => unreachable!(),
});
last_comma = false;
continue;
}

if ch == ']' || ch == '}' {
curr_indentlv -= 1;
if !last_comma {
result.push('\n');
for _ in 0..(curr_indentlv * setting.indent_width) {
result.push(' ');
}
}
result.push(ch);
ctx.pop();
continue;
}

if ch == ':' {
result.push(ch);
result.push(' ');
continue;
}

result.push(ch);
}
result.push('\n');

result
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct PrettySetting {
pub indent_width: u32,
}
17 changes: 15 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
extern crate minjson;


use std::env;
use std::io::Read;

use std::io;

fn main() -> () {
let args: Vec<String> = env::args().collect();
if args.len() != 2 || (args[1] != "minify" && args[1] != "pretty") {
eprintln!("Wrong number of arguments");
eprintln!("Usage: minjson <operation>");
eprintln!("<operation> := minify | pretty");
return;
}

let mut strbuf = String::new();
io::stdin().read_to_string(&mut strbuf).expect("Unable to read json");

let res = minjson::minimize_json(&strbuf);
let res: String;
if args[1] == "minify" {
res = minjson::minimize_json(&strbuf);
} else {
res = minjson::pretty_json(&strbuf, &minjson::PrettySetting{indent_width: 2});
}

print!("{}", res);
}

0 comments on commit e97bfc6

Please sign in to comment.