mirror of
https://github.com/Noratrieb/jsonformat.git
synced 2026-01-14 14:15:03 +01:00
binary cleanup
This commit is contained in:
parent
c5e63a743a
commit
35332a1b26
7 changed files with 59 additions and 31 deletions
5
CHANGELOG.md
Normal file
5
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
# 2.0.0
|
||||||
|
|
||||||
|
There are many changes, the two formatting functions have been renamed, `format_reader_writer` now takes
|
||||||
|
a `W` and `R` instead of `&mut BufReader<W>`, it now always adds a trailing newline. There may be a few more
|
||||||
|
small changes.
|
||||||
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -299,7 +299,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonformat-cli"
|
name = "jsonformat-cli"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap 3.1.12",
|
"clap 3.1.12",
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,6 @@ OPTIONS:
|
||||||
Reads from stdin if no file is supplied.
|
Reads from stdin if no file is supplied.
|
||||||
Outputs to stdout if no output file is specified.
|
Outputs to stdout if no output file is specified.
|
||||||
|
|
||||||
On Windows, it writes to a file called `<filename>_f.json`, unless the `--stdout` flag is used or a custom output
|
|
||||||
file is provided. This it to enable drag-and-drop in Windows explorer.
|
|
||||||
|
|
||||||
## Error handling
|
## Error handling
|
||||||
`jsonformat` does not report malformed json - it can't even fully know whether the json is actually malformed.
|
`jsonformat` does not report malformed json - it can't even fully know whether the json is actually malformed.
|
||||||
Malformed json is just formatted kind of incorrectly, with no data lost and no crashes. If you find one, open an issue,
|
Malformed json is just formatted kind of incorrectly, with no data lost and no crashes. If you find one, open an issue,
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,26 @@
|
||||||
use std::{fs, io};
|
use std::{fs, io, path::PathBuf};
|
||||||
|
|
||||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||||
use jsonformat::{format, format_reader_writer, Indentation};
|
use jsonformat::{format, format_reader_writer, Indentation};
|
||||||
|
|
||||||
fn criterion_benchmark(c: &mut Criterion) {
|
fn criterion_benchmark(c: &mut Criterion) {
|
||||||
let file = include_str!("large-file.json");
|
// using `include_str` makes the benches a lot less reliable for some reason???
|
||||||
|
let file = PathBuf::from(file!())
|
||||||
|
.parent()
|
||||||
|
.unwrap()
|
||||||
|
.join("large-file.json");
|
||||||
|
let file = fs::read_to_string(file).unwrap();
|
||||||
|
|
||||||
c.bench_function("Format json default settings", |b| {
|
c.bench_function("Format json default settings", |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let json = format(&file, Indentation::Default);
|
let json = format(black_box(&file), Indentation::TwoSpace);
|
||||||
black_box(json);
|
black_box(json);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
c.bench_function("Format json custom indentation", |b| {
|
c.bench_function("Format json custom indentation", |b| {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let json = format(&file, Indentation::Custom("123456"));
|
let json = format(black_box(&file), Indentation::Custom("123456"));
|
||||||
black_box(json);
|
black_box(json);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
@ -24,7 +29,12 @@ fn criterion_benchmark(c: &mut Criterion) {
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let mut writer = Vec::with_capacity(file.len() * 2);
|
let mut writer = Vec::with_capacity(file.len() * 2);
|
||||||
|
|
||||||
format_reader_writer(file.as_bytes(), &mut writer, Indentation::Default).unwrap();
|
format_reader_writer(
|
||||||
|
black_box(file.as_bytes()),
|
||||||
|
&mut writer,
|
||||||
|
Indentation::TwoSpace,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
black_box(writer);
|
black_box(writer);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "jsonformat-cli"
|
name = "jsonformat-cli"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
authors = ["Nilstrieb <nilstrieb@gmail.com>"]
|
authors = ["Nilstrieb <nilstrieb@gmail.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,13 @@ use jsonformat::{format_reader_writer, Indentation};
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[clap(author, about, version)]
|
#[clap(author, about, version)]
|
||||||
struct Options {
|
struct Options {
|
||||||
|
/// The indentation, s will replaced by a space and t by a tab. ss is the default.
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
indentation: Option<String>,
|
indentation: Option<String>,
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
|
/// The output file
|
||||||
output: Option<PathBuf>,
|
output: Option<PathBuf>,
|
||||||
|
/// The input file
|
||||||
input: Option<PathBuf>,
|
input: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,7 +54,7 @@ fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
let indent = match replaced_indent {
|
let indent = match replaced_indent {
|
||||||
Some(ref str) => Indentation::Custom(str),
|
Some(ref str) => Indentation::Custom(str),
|
||||||
None => Indentation::Default,
|
None => Indentation::TwoSpace,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Note: on-stack dynamic dispatch
|
// Note: on-stack dynamic dispatch
|
||||||
|
|
|
||||||
53
src/lib.rs
53
src/lib.rs
|
|
@ -15,11 +15,17 @@ use std::{
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
pub enum Indentation<'a> {
|
pub enum Indentation<'a> {
|
||||||
/// Use the default indentation, which is two spaces
|
/// Use the default indentation, which is two spaces
|
||||||
Default,
|
TwoSpace,
|
||||||
/// Use a custom indentation String
|
/// Use a custom indentation String
|
||||||
Custom(&'a str),
|
Custom(&'a str),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for Indentation<'_> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::TwoSpace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// # Formats a json string
|
/// # Formats a json string
|
||||||
///
|
///
|
||||||
/// The indentation can be set to any value using [`Indentation`]
|
/// The indentation can be set to any value using [`Indentation`]
|
||||||
|
|
@ -91,7 +97,7 @@ where
|
||||||
indent_level = indent_level.saturating_sub(1);
|
indent_level = indent_level.saturating_sub(1);
|
||||||
if !newline_requested {
|
if !newline_requested {
|
||||||
// see comment below about newline_requested
|
// see comment below about newline_requested
|
||||||
writer.write_all(&[b'\n'])?;
|
writer.write_all(b"\n")?;
|
||||||
indent(&mut writer, indent_level, indentation)?;
|
indent(&mut writer, indent_level, indentation)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -109,7 +115,7 @@ where
|
||||||
// newline only happens after { [ and ,
|
// newline only happens after { [ and ,
|
||||||
// this means we can safely assume that it being followed up by } or ]
|
// this means we can safely assume that it being followed up by } or ]
|
||||||
// means an empty object/array
|
// means an empty object/array
|
||||||
writer.write_all(&[b'\n'])?;
|
writer.write_all(b"\n")?;
|
||||||
indent(&mut writer, old_level, indentation)?;
|
indent(&mut writer, old_level, indentation)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,6 +127,9 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trailing newline
|
||||||
|
writer.write_all(b"\n")?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,7 +139,7 @@ where
|
||||||
{
|
{
|
||||||
for _ in 0..level {
|
for _ in 0..level {
|
||||||
match indent_str {
|
match indent_str {
|
||||||
Indentation::Default => {
|
Indentation::TwoSpace => {
|
||||||
writer.write_all(b" ")?;
|
writer.write_all(b" ")?;
|
||||||
}
|
}
|
||||||
Indentation::Custom(indent) => {
|
Indentation::Custom(indent) => {
|
||||||
|
|
@ -148,28 +157,28 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn echoes_primitive() {
|
fn echoes_primitive() {
|
||||||
let json = "1.35";
|
let json = "1.35\n";
|
||||||
assert_eq!(json, format(json, Indentation::Default));
|
assert_eq!(json, format(json, Indentation::TwoSpace));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ignore_whitespace_in_string() {
|
fn ignore_whitespace_in_string() {
|
||||||
let json = "\" hallo \"";
|
let json = "\" hallo \"\n";
|
||||||
assert_eq!(json, format(json, Indentation::Default));
|
assert_eq!(json, format(json, Indentation::TwoSpace));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn remove_leading_whitespace() {
|
fn remove_leading_whitespace() {
|
||||||
let json = " 0";
|
let json = " 0";
|
||||||
let expected = "0";
|
let expected = "0\n";
|
||||||
assert_eq!(expected, format(json, Indentation::Default));
|
assert_eq!(expected, format(json, Indentation::TwoSpace));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn handle_escaped_strings() {
|
fn handle_escaped_strings() {
|
||||||
let json = " \" hallo \\\" \" ";
|
let json = " \" hallo \\\" \" ";
|
||||||
let expected = "\" hallo \\\" \"";
|
let expected = "\" hallo \\\" \"\n";
|
||||||
assert_eq!(expected, format(json, Indentation::Default));
|
assert_eq!(expected, format(json, Indentation::TwoSpace));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -177,8 +186,9 @@ mod test {
|
||||||
let json = "{\"a\":0}";
|
let json = "{\"a\":0}";
|
||||||
let expected = "{
|
let expected = "{
|
||||||
\"a\": 0
|
\"a\": 0
|
||||||
}";
|
}
|
||||||
assert_eq!(expected, format(json, Indentation::Default));
|
";
|
||||||
|
assert_eq!(expected, format(json, Indentation::TwoSpace));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -188,8 +198,9 @@ mod test {
|
||||||
1,
|
1,
|
||||||
2,
|
2,
|
||||||
null
|
null
|
||||||
]";
|
]
|
||||||
assert_eq!(expected, format(json, Indentation::Default));
|
";
|
||||||
|
assert_eq!(expected, format(json, Indentation::TwoSpace));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -203,9 +214,10 @@ mod test {
|
||||||
{
|
{
|
||||||
\"a\": null
|
\"a\": null
|
||||||
}
|
}
|
||||||
]";
|
]
|
||||||
|
";
|
||||||
|
|
||||||
assert_eq!(expected, format(json, Indentation::Default));
|
assert_eq!(expected, format(json, Indentation::TwoSpace));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -218,8 +230,9 @@ mod test {
|
||||||
{
|
{
|
||||||
\"a\": null
|
\"a\": null
|
||||||
}
|
}
|
||||||
]";
|
]
|
||||||
|
";
|
||||||
|
|
||||||
assert_eq!(expected, format(expected, Indentation::Default));
|
assert_eq!(expected, format(expected, Indentation::TwoSpace));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue