mirror of
https://github.com/Noratrieb/jsonformat.git
synced 2026-01-14 22:25:01 +01:00
options
This commit is contained in:
parent
d0733b1a7c
commit
9b7260660e
5 changed files with 320 additions and 30 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -4,3 +4,6 @@
|
||||||
|
|
||||||
# test data
|
# test data
|
||||||
*.json
|
*.json
|
||||||
|
|
||||||
|
# local install script
|
||||||
|
install.sh
|
||||||
248
Cargo.lock
generated
248
Cargo.lock
generated
|
|
@ -1,5 +1,253 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "atty"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||||
|
dependencies = [
|
||||||
|
"hermit-abi",
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "3.0.0-beta.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142"
|
||||||
|
dependencies = [
|
||||||
|
"atty",
|
||||||
|
"bitflags",
|
||||||
|
"clap_derive",
|
||||||
|
"indexmap",
|
||||||
|
"lazy_static",
|
||||||
|
"os_str_bytes",
|
||||||
|
"strsim",
|
||||||
|
"termcolor",
|
||||||
|
"textwrap",
|
||||||
|
"unicode-width",
|
||||||
|
"vec_map",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "3.0.0-beta.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-abi"
|
||||||
|
version = "0.1.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonformat"
|
name = "jsonformat"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.98"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "os_str_bytes"
|
||||||
|
version = "2.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error-attr",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error-attr"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.73"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "termcolor"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "textwrap"
|
||||||
|
version = "0.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-width",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vec_map"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-i686-pc-windows-gnu",
|
||||||
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-i686-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||||
|
|
|
||||||
|
|
@ -8,3 +8,4 @@ description = "Reads raw json from stdin and formats it to stdout"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
clap = "3.0.0-beta.2"
|
||||||
48
src/lib.rs
48
src/lib.rs
|
|
@ -1,5 +1,14 @@
|
||||||
pub fn format_json(json: &str, indent_str: &str) -> String {
|
///
|
||||||
let mut out = String::with_capacity(json.len()); // at least as big as the input
|
/// # Formats a json string
|
||||||
|
///
|
||||||
|
/// The indentation can be set to any custom value
|
||||||
|
/// The default value is two spaces
|
||||||
|
/// The default indentation is faster than a custom one
|
||||||
|
///
|
||||||
|
pub fn format_json(json: &str, indentation: Option<&str>) -> String {
|
||||||
|
// at least as big as the input to avoid resizing
|
||||||
|
// this might be too big if the input string is formatted in a weird way, but that's not expected
|
||||||
|
let mut out = String::with_capacity(json.len());
|
||||||
|
|
||||||
let mut escaped = false;
|
let mut escaped = false;
|
||||||
let mut in_string = false;
|
let mut in_string = false;
|
||||||
|
|
@ -42,9 +51,9 @@ pub fn format_json(json: &str, indent_str: &str) -> String {
|
||||||
'}' | ']' => {
|
'}' | ']' => {
|
||||||
indent_level -= 1;
|
indent_level -= 1;
|
||||||
if !newline_requested {
|
if !newline_requested {
|
||||||
// see comment above
|
// see comment below about newline_requested
|
||||||
out.push('\n');
|
out.push('\n');
|
||||||
indent(&mut out, indent_level, indent_str);
|
indent(&mut out, indent_level, indentation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
':' => {
|
':' => {
|
||||||
|
|
@ -59,8 +68,10 @@ pub fn format_json(json: &str, indent_str: &str) -> String {
|
||||||
}
|
}
|
||||||
if newline_requested && char != ']' && char != '}' {
|
if newline_requested && char != ']' && char != '}' {
|
||||||
// newline only happens after { [ and ,
|
// newline only happens after { [ and ,
|
||||||
|
// this means we can safely assume that it being followed up by } or ]
|
||||||
|
// means an empty object/array
|
||||||
out.push('\n');
|
out.push('\n');
|
||||||
indent(&mut out, old_level, indent_str);
|
indent(&mut out, old_level, indentation);
|
||||||
}
|
}
|
||||||
|
|
||||||
if auto_push {
|
if auto_push {
|
||||||
|
|
@ -74,41 +85,48 @@ pub fn format_json(json: &str, indent_str: &str) -> String {
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
fn indent(buf: &mut String, level: usize, indent_str: &str) {
|
fn indent(buf: &mut String, level: usize, indent_str: Option<&str>) {
|
||||||
for _ in 0..level {
|
for _ in 0..level {
|
||||||
buf.push_str(indent_str);
|
match indent_str {
|
||||||
|
None => {
|
||||||
|
buf.push(' ');
|
||||||
|
buf.push(' ');
|
||||||
|
}
|
||||||
|
Some(indent) => {
|
||||||
|
buf.push_str(indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
const INDENT: &str = " ";
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn echoes_primitive() {
|
fn echoes_primitive() {
|
||||||
let json = "1.35";
|
let json = "1.35";
|
||||||
assert_eq!(json, format_json(json, INDENT));
|
assert_eq!(json, format_json(json, None));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ignore_whitespace_in_string() {
|
fn ignore_whitespace_in_string() {
|
||||||
let json = "\" hallo \"";
|
let json = "\" hallo \"";
|
||||||
assert_eq!(json, format_json(json, INDENT));
|
assert_eq!(json, format_json(json, None));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn remove_leading_whitespace() {
|
fn remove_leading_whitespace() {
|
||||||
let json = " 0";
|
let json = " 0";
|
||||||
let expected = "0";
|
let expected = "0";
|
||||||
assert_eq!(expected, format_json(json, INDENT));
|
assert_eq!(expected, format_json(json, None));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn handle_escaped_strings() {
|
fn handle_escaped_strings() {
|
||||||
let json = " \" hallo \\\" \" ";
|
let json = " \" hallo \\\" \" ";
|
||||||
let expected = "\" hallo \\\" \"";
|
let expected = "\" hallo \\\" \"";
|
||||||
assert_eq!(expected, format_json(json, INDENT));
|
assert_eq!(expected, format_json(json, None));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -117,7 +135,7 @@ mod test {
|
||||||
let expected = "{
|
let expected = "{
|
||||||
\"a\": 0
|
\"a\": 0
|
||||||
}";
|
}";
|
||||||
assert_eq!(expected, format_json(json, INDENT));
|
assert_eq!(expected, format_json(json, None));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -128,7 +146,7 @@ mod test {
|
||||||
2,
|
2,
|
||||||
null
|
null
|
||||||
]";
|
]";
|
||||||
assert_eq!(expected, format_json(json, INDENT));
|
assert_eq!(expected, format_json(json, None));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -144,6 +162,6 @@ mod test {
|
||||||
}
|
}
|
||||||
]";
|
]";
|
||||||
|
|
||||||
assert_eq!(expected, format_json(json, INDENT));
|
assert_eq!(expected, format_json(json, None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
26
src/main.rs
26
src/main.rs
|
|
@ -1,12 +1,21 @@
|
||||||
|
use clap::clap_app;
|
||||||
use jsonformat::format_json;
|
use jsonformat::format_json;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
|
||||||
fn main() -> Result<(), io::Error> {
|
fn main() -> Result<(), io::Error> {
|
||||||
let filename = std::env::args().skip(1).next();
|
let matches = clap_app!(jsonformat =>
|
||||||
|
(version: "1.0")
|
||||||
|
(author: "nilstrieb <nilstrieb@gmail.com>")
|
||||||
|
(about: "Formats json")
|
||||||
|
(@arg indentation: -i --indent +takes_value "Set the indentation used (\\s for space, \\t for tab)")
|
||||||
|
(@arg output: -o --output +takes_value "The output file for the formatted json")
|
||||||
|
(@arg input: "The input file to format")
|
||||||
|
)
|
||||||
|
.get_matches();
|
||||||
|
|
||||||
let str = match filename {
|
let str = match matches.value_of("input") {
|
||||||
Some(path) => fs::read_to_string(path)?,
|
Some(path) => fs::read_to_string(path)?,
|
||||||
None => {
|
None => {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
@ -16,7 +25,18 @@ fn main() -> Result<(), io::Error> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
println!("{}", format_json(&str, " "));
|
let replaced_indent = matches
|
||||||
|
.value_of("indentation")
|
||||||
|
.map(|value| value.replace("s", " ").replace("t", "\t"));
|
||||||
|
|
||||||
|
let formatted = format_json(&str, replaced_indent.as_deref());
|
||||||
|
|
||||||
|
match matches.value_of("output") {
|
||||||
|
Some(file) => {
|
||||||
|
fs::write(file, formatted)?;
|
||||||
|
}
|
||||||
|
None => println!("{}", formatted),
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue