Skip to main content

grapheme_stdlib/
csv.rs

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(|| args.get("__input").and_then(|v| v.as_str()).map(ToOwned::to_owned))
40        .unwrap_or_default()
41}