1use serde_json::{json, Value as JsonValue};
2
3pub fn to_list(args: &JsonValue) -> JsonValue {
4 let text = arg_text(args, "text");
5 let mut reader = csv::ReaderBuilder::new()
6 .has_headers(true)
7 .from_reader(text.as_bytes());
8
9 let headers = match reader.headers() {
10 Ok(h) => h.iter().map(|s| s.to_string()).collect::<Vec<_>>(),
11 Err(err) => return json!({ "error": format!("csv header parse failed: {err}") }),
12 };
13
14 let mut rows = Vec::new();
15 for record in reader.records() {
16 let record = match record {
17 Ok(r) => r,
18 Err(err) => return json!({ "error": format!("csv row parse failed: {err}") }),
19 };
20
21 let mut obj = serde_json::Map::new();
22 for (idx, value) in record.iter().enumerate() {
23 let key = headers
24 .get(idx)
25 .cloned()
26 .unwrap_or_else(|| format!("col_{idx}"));
27 obj.insert(key, JsonValue::String(value.to_string()));
28 }
29 rows.push(JsonValue::Object(obj));
30 }
31
32 JsonValue::Array(rows)
33}
34
35fn arg_text(args: &JsonValue, key: &str) -> String {
36 args.get(key)
37 .and_then(|v| v.as_str())
38 .map(ToOwned::to_owned)
39 .or_else(|| {
40 args.get("__input")
41 .and_then(|v| v.as_str())
42 .map(ToOwned::to_owned)
43 })
44 .unwrap_or_default()
45}