Skip to content

Commit

Permalink
Merge pull request #2167 from jqnatividad/json-empty-error
Browse files Browse the repository at this point in the history
`json`: add error for empty key and update usage text

Awesome! Just made it to the 0.135.0 release... thanks @rzmk !
  • Loading branch information
jqnatividad authored Sep 24, 2024
2 parents a5a6711 + 1babc7d commit ed1362d
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 4 deletions.
18 changes: 14 additions & 4 deletions src/cmd/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ Convert JSON to CSV.
The JSON data is expected to be non-empty and non-nested as either:
1. An array of objects where:
A. All objects are non-empty and have the same keys.
A. All objects are non-empty, have non-empty and unique keys, and the same keys are in each object.
B. Values are not objects or arrays.
2. An object where values are not objects or arrays.
2. An object where values are not objects or arrays and the object is as described above.
Objects with duplicate keys are not recommended as only one key and its values may be used.
If your JSON data is not in the expected format and/or is nested or complex, try using
the --jaq option to pass a jq-like filter before parsing with the above constraints.
Expand Down Expand Up @@ -80,8 +82,8 @@ json options:
which is identical to the popular JSON command-line tool - jq.
https://jqlang.github.io/jq/
Note that the filter is applied BEFORE converting JSON to CSV
-s, --select <cols> Select, reorder or drop columns for output.
Otherwise, all the columns will be output in the same order as
-s, --select <cols> Select, reorder or drop columns for output.
Otherwise, all the columns will be output in the same order as
the first object's keys in the JSON data.
See 'qsv select --help' for the full syntax.
Note however that <cols> NEED to be a comma-delimited list
Expand Down Expand Up @@ -218,6 +220,14 @@ pub fn run(argv: &[&str]) -> CliResult<()> {
}
let mut first_dict_headers: Vec<&str> = Vec::new();
for key in first_dict.keys() {
if key.is_empty() {
return Err(CliError::Other("Expected a non-empty JSON key".to_string()));
}
if first_dict_headers.contains(&key.as_str()) {
return Err(CliError::Other(format!(
"Expected non-duplicate keys, found key: {key}"
)));
}
first_dict_headers.push(key.as_str());
}

Expand Down
47 changes: 47 additions & 0 deletions tests/test_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,3 +328,50 @@ fn json_nested() {

assert_eq!(got, expected);
}

#[test]
#[serial]
fn json_empty_keys_with_jaq() {
let wrk = Workdir::new("json_empty_keys_with_jaq");
let json_data = serde_json::json!({
"data": [
{
"fruit": "apple",
"": 0.50
},
{
"fruit": "banana",
"": 1.00
}
]
});
let filter = ".data";

wrk.create_from_string("data.json", json_data.to_string().as_str());
let mut cmd = wrk.command("json");
cmd.arg("data.json");
cmd.args(vec!["--jaq", filter]);

wrk.assert_err(&mut cmd);
}

#[test]
#[serial]
fn json_empty_keys() {
let wrk = Workdir::new("json_empty_keys");
let json_data = serde_json::json!([
{
"fruit": "apple",
"": 0.50
},
{
"fruit": "banana",
"": 1.00
}
]);
wrk.create_from_string("data.json", json_data.to_string().as_str());
let mut cmd = wrk.command("json");
cmd.arg("data.json");

wrk.assert_err(&mut cmd);
}

0 comments on commit ed1362d

Please sign in to comment.