1 //! CSV impl and reexported types 2 3 extern crate csv; 4 5 pub use self::csv::{Reader, Writer, Result, ReaderBuilder}; 6 use std::path::Path; 7 use std::io::{Read, Write}; 8 9 impl<'a> super::TableSlice<'a> { 10 /// Write the table to the specified writer. to_csv<W: Write>(&self, w: W) -> Result<Writer<W>>11 pub fn to_csv<W: Write>(&self, w: W) -> Result<Writer<W>> { 12 self.to_csv_writer(Writer::from_writer(w)) 13 } 14 15 /// Write the table to the specified writer. 16 /// 17 /// This allows for format customisation. to_csv_writer<W: Write>(&self, mut writer: Writer<W>) -> Result<Writer<W>>18 pub fn to_csv_writer<W: Write>(&self, 19 mut writer: Writer<W>) 20 -> Result<Writer<W>> { 21 for title in self.titles { 22 writer.write_record(title.iter().map(|c| c.get_content()))?; 23 } 24 for row in self.rows { 25 writer.write_record(row.iter().map(|c| c.get_content()))?; 26 } 27 28 writer.flush()?; 29 Ok(writer) 30 } 31 } 32 33 impl super::Table { 34 /// Create a table from a CSV string 35 /// 36 /// For more customisability use `from_csv()` from_csv_string(csv_s: &str) -> Result<Self>37 pub fn from_csv_string(csv_s: &str) -> Result<Self> { 38 Ok(Self::from_csv( 39 &mut ReaderBuilder::new() 40 .has_headers(false) 41 .from_reader(csv_s.as_bytes()))) 42 } 43 44 /// Create a table from a CSV file 45 /// 46 /// For more customisability use `from_csv()` from_csv_file<P: AsRef<Path>>(csv_p: P) -> Result<Self>47 pub fn from_csv_file<P: AsRef<Path>>(csv_p: P) -> Result<Self> { 48 Ok(Self::from_csv( 49 &mut ReaderBuilder::new() 50 .has_headers(false) 51 .from_path(csv_p)?)) 52 } 53 54 /// Create a table from a CSV reader from_csv<R: Read>(reader: &mut Reader<R>) -> Self55 pub fn from_csv<R: Read>(reader: &mut Reader<R>) -> Self { 56 Self::init(reader 57 .records() 58 .map(|row| { 59 super::Row::new(row.unwrap() 60 .into_iter() 61 .map(|cell| super::Cell::new(&cell)) 62 .collect()) 63 }) 64 .collect()) 65 } 66 67 68 /// Write the table to the specified writer. to_csv<W: Write>(&self, w: W) -> Result<Writer<W>>69 pub fn to_csv<W: Write>(&self, w: W) -> Result<Writer<W>> { 70 self.as_ref().to_csv(w) 71 } 72 73 /// Write the table to the specified writer. 74 /// 75 /// This allows for format customisation. to_csv_writer<W: Write>(&self, writer: Writer<W>) -> Result<Writer<W>>76 pub fn to_csv_writer<W: Write>(&self, writer: Writer<W>) -> Result<Writer<W>> { 77 self.as_ref().to_csv_writer(writer) 78 } 79 } 80 81 82 #[cfg(test)] 83 mod tests { 84 use {Table, Row, Cell}; 85 86 static CSV_S: &'static str = "ABC,DEFG,HIJKLMN\n\ 87 foobar,bar,foo\n\ 88 foobar2,bar2,foo2\n"; 89 test_table() -> Table90 fn test_table() -> Table { 91 let mut table = Table::new(); 92 table 93 .add_row(Row::new(vec![Cell::new("ABC"), Cell::new("DEFG"), Cell::new("HIJKLMN")])); 94 table.add_row(Row::new(vec![Cell::new("foobar"), Cell::new("bar"), Cell::new("foo")])); 95 table.add_row(Row::new(vec![Cell::new("foobar2"), 96 Cell::new("bar2"), 97 Cell::new("foo2")])); 98 table 99 } 100 101 #[test] from()102 fn from() { 103 assert_eq!(test_table().to_string().replace("\r\n", "\n"), 104 Table::from_csv_string(CSV_S) 105 .unwrap() 106 .to_string() 107 .replace("\r\n", "\n")); 108 } 109 110 #[test] to()111 fn to() { 112 assert_eq!( 113 String::from_utf8( 114 test_table() 115 .to_csv(Vec::new()) 116 .unwrap() 117 .into_inner() 118 .unwrap() 119 ).unwrap(), 120 CSV_S); 121 } 122 123 #[test] trans()124 fn trans() { 125 assert_eq!( 126 Table::from_csv_string( 127 &String::from_utf8( 128 test_table() 129 .to_csv(Vec::new()) 130 .unwrap() 131 .into_inner() 132 .unwrap() 133 ).unwrap() 134 ).unwrap() 135 .to_string() 136 .replace("\r\n", "\n"), 137 test_table().to_string().replace("\r\n", "\n")); 138 } 139 140 #[test] extend_table()141 fn extend_table() { 142 let mut table = Table::new(); 143 table.add_row(Row::new(vec![Cell::new("ABC"), Cell::new("DEFG"), Cell::new("HIJKLMN")])); 144 table.extend(vec![vec!["A", "B", "C"]]); 145 let t2 = table.clone(); 146 table.extend(t2.rows); 147 assert_eq!(table.get_row(1).unwrap().get_cell(2).unwrap().get_content(), "C"); 148 assert_eq!(table.get_row(2).unwrap().get_cell(1).unwrap().get_content(), "DEFG"); 149 } 150 }