imp(CLI): remove null in pretty-printed json

Without all that clutter, it's so much more enjoyable to read the
output.

The implementation is based on a suggestion of @erickt, which is
converts into a json::Value (able to represent any json structure),
on which the filtering is applied.

If we should ever implement pretty-printing in json-tools, we might
still consider using these capabilities instead, as we would avoid
building potentially large datastructures, all we would need is
a sufficiently large destination buffer which is a single alloc and
a consecutive region in memory.

Closes #102
[skip ci]
This commit is contained in:
Sebastian Thiel
2015-05-08 19:09:47 +02:00
parent 26314e743e
commit 5894c8163a
2 changed files with 27 additions and 2 deletions

View File

@@ -32,7 +32,7 @@
%>\
use cmn::{InvalidOptionsError, CLIError, JsonTokenStorage, arg_from_str, writer_from_opts, parse_kv_arg,
input_file_from_opts, input_mime_from_opts, FieldCursor, FieldError, CallType, UploadProtocol,
calltype_from_str};
calltype_from_str, remove_json_null_values};
use std::default::Default;
use std::str::FromStr;
@@ -318,7 +318,9 @@ if dry_run {
if !download_mode {
% endif
% if mc.response_schema:
serde::json::to_writer_pretty(&mut ostream, &output_schema).unwrap();
let mut value = json::value::to_value(&output_schema);
remove_json_null_values(&mut value);
serde::json::to_writer_pretty(&mut ostream, &value).unwrap();
% endif
% if track_download_flag:
} else {

View File

@@ -17,6 +17,29 @@ use std::default::Default;
const FIELD_SEP: char = '.';
// Based on @erickt user comment. Thanks for the idea !
// Remove all keys whose values are null from given value (changed in place)
pub fn remove_json_null_values(value: &mut json::value::Value) {
match *value {
json::value::Value::Object(ref mut map) => {
let mut for_removal = Vec::new();
for (key, mut value) in map.iter_mut() {
if value.is_null() {
for_removal.push(key.clone());
} else {
remove_json_null_values(&mut value);
}
}
for key in &for_removal {
map.remove(key);
}
}
_ => {}
}
}
fn did_you_mean<'a>(v: &str, possible_values: &[&'a str]) -> Option<&'a str> {
let mut candidate: Option<(f64, &str)> = None;