windjammer_runtime/
csv_mod.rs1use csv::Writer;
6use std::io::Cursor;
7
8pub fn parse(data: &str) -> Result<Vec<Vec<String>>, String> {
10 let mut reader = csv::ReaderBuilder::new()
11 .has_headers(false) .from_reader(Cursor::new(data));
13 let mut rows = Vec::new();
14
15 for result in reader.records() {
16 let record = result.map_err(|e| e.to_string())?;
17 let row: Vec<String> = record.iter().map(|s| s.to_string()).collect();
18 rows.push(row);
19 }
20
21 Ok(rows)
22}
23
24pub fn write(rows: &[Vec<String>]) -> Result<String, String> {
26 let mut writer = Writer::from_writer(vec![]);
27
28 for row in rows {
29 writer.write_record(row).map_err(|e| e.to_string())?;
30 }
31
32 let data = writer.into_inner().map_err(|e| e.to_string())?;
33 String::from_utf8(data).map_err(|e| e.to_string())
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
41 fn test_parse() {
42 let csv = "a,b,c\n1,2,3\n4,5,6";
43 let rows = parse(csv).unwrap();
44 assert_eq!(rows.len(), 3);
46 assert_eq!(rows[0], vec!["a", "b", "c"]);
47 assert_eq!(rows[1], vec!["1", "2", "3"]);
48 assert_eq!(rows[2], vec!["4", "5", "6"]);
49 }
50
51 #[test]
52 fn test_write() {
53 let rows = vec![
54 vec!["a".to_string(), "b".to_string()],
55 vec!["1".to_string(), "2".to_string()],
56 ];
57 let csv = write(&rows).unwrap();
58 assert!(csv.contains("a,b"));
59 assert!(csv.contains("1,2"));
60 }
61}