Skip to content

Commit ca1a241

Browse files
committed
refactor: parse --json-values once as serde_json::Value, then branch
Address Gemini review: avoid parsing the JSON string twice. Now parses once into a generic Value, then branches on whether it's a nested array (multi-row) or flat array (single row). Also rejects non-array JSON (objects, scalars) with a clear error.
1 parent 4b677f5 commit ca1a241

1 file changed

Lines changed: 26 additions & 7 deletions

File tree

src/helpers/sheets.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -274,16 +274,35 @@ pub struct AppendConfig {
274274
/// Returns a validation error if `--json-values` contains invalid JSON.
275275
pub fn parse_append_args(matches: &ArgMatches) -> Result<AppendConfig, GwsError> {
276276
let values = if let Some(json_str) = matches.get_one::<String>("json-values") {
277-
// Parse JSON array of rows
278-
if let Ok(parsed) = serde_json::from_str::<Vec<Vec<String>>>(json_str) {
279-
parsed.into_iter().flatten().collect()
280-
} else {
281-
// Treat as single row JSON array
282-
serde_json::from_str::<Vec<String>>(json_str).map_err(|e| {
277+
// Parse once as a generic JSON Value, then branch on structure.
278+
let parsed: serde_json::Value =
279+
serde_json::from_str(json_str).map_err(|e| {
283280
GwsError::Validation(format!(
284281
"--json-values is not valid JSON: {e}. Expected a JSON array like '[\"a\",\"b\"]' or '[[\"a\",\"b\"],[\"c\",\"d\"]]'."
285282
))
286-
})?
283+
})?;
284+
285+
match parsed {
286+
// Multi-row: [[...], [...]]
287+
serde_json::Value::Array(ref rows)
288+
if rows.first().is_some_and(|r| r.is_array()) =>
289+
{
290+
rows.iter()
291+
.filter_map(|row| row.as_array())
292+
.flatten()
293+
.filter_map(|v| v.as_str().map(|s| s.to_string()))
294+
.collect()
295+
}
296+
// Single row: [...]
297+
serde_json::Value::Array(ref items) => items
298+
.iter()
299+
.filter_map(|v| v.as_str().map(|s| s.to_string()))
300+
.collect(),
301+
_ => {
302+
return Err(GwsError::Validation(
303+
"--json-values must be a JSON array, not an object or scalar.".to_string(),
304+
));
305+
}
287306
}
288307
} else if let Some(values_str) = matches.get_one::<String>("values") {
289308
values_str.split(',').map(|s| s.to_string()).collect()

0 commit comments

Comments
 (0)