diff --git a/.changeset/fix-csv-array-of-arrays.md b/.changeset/fix-csv-array-of-arrays.md new file mode 100644 index 00000000..b0682ed3 --- /dev/null +++ b/.changeset/fix-csv-array-of-arrays.md @@ -0,0 +1,5 @@ +--- +"@googleworkspace/cli": patch +--- + +Fix `--format csv` for array-of-arrays responses (e.g. Sheets values API) diff --git a/src/formatter.rs b/src/formatter.rs index 1b069668..00f50340 100644 --- a/src/formatter.rs +++ b/src/formatter.rs @@ -356,6 +356,23 @@ fn format_csv_page(value: &Value, emit_header: bool) -> String { return String::new(); } + // Array of non-objects + if !arr.iter().any(|v| v.is_object()) { + let mut output = String::new(); + for item in arr { + if let Value::Array(inner) = item { + let cells: Vec = inner + .iter() + .map(|v| csv_escape(&value_to_cell(v))) + .collect(); + let _ = writeln!(output, "{}", cells.join(",")); + } else { + let _ = writeln!(output, "{}", csv_escape(&value_to_cell(item))); + } + } + return output; + } + // Collect columns let mut columns: Vec = Vec::new(); for item in arr { @@ -564,6 +581,23 @@ mod tests { assert!(output.contains("2,world")); } + #[test] + fn test_format_csv_array_of_arrays() { + // Sheets API returns {"values": [["col1","col2"], ["a","b"]]} + let val = json!({ + "values": [ + ["Student Name", "Gender", "Class Level"], + ["Alexandra", "Female", "4. Senior"], + ["Andrew", "Male", "1. Freshman"] + ] + }); + let output = format_value(&val, &OutputFormat::Csv); + let lines: Vec<&str> = output.lines().collect(); + assert_eq!(lines[0], "Student Name,Gender,Class Level"); + assert_eq!(lines[1], "Alexandra,Female,4. Senior"); + assert_eq!(lines[2], "Andrew,Male,1. Freshman"); + } + #[test] fn test_format_csv_escape() { assert_eq!(csv_escape("simple"), "simple");