summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPierre-Henri Symoneaux <pierre-henri.symoneaux@nokia.com>2016-09-13 21:11:07 +0200
committerPierre-Henri Symoneaux <pierre-henri.symoneaux@nokia.com>2016-09-13 21:11:07 +0200
commit5a4251deb80bdd3d16460f0224ee9928b4f42736 (patch)
tree8c8e0efb4333db30395f4ab2a8b08dbfaffc53df
parente11621c19ce2c68c0052be04080be75a6ba66396 (diff)
parent0b26d80739ed733e6f59877e744248fd19334bd8 (diff)
Merge remote-tracking branch 'refs/remotes/nabijaczleweli/master'
Conflicts: Cargo.toml src/lib.rs
-rw-r--r--Cargo.toml1
-rw-r--r--examples/csv.rs26
-rw-r--r--src/lib.rs116
3 files changed, 128 insertions, 15 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 668167c..a3ab1bd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,3 +27,4 @@ term = "^0.4"
lazy_static = "^0.2"
atty = "^0.2"
encode_unicode = "^0.2"
+csv = "^0.14"
diff --git a/examples/csv.rs b/examples/csv.rs
new file mode 100644
index 0000000..df14173
--- /dev/null
+++ b/examples/csv.rs
@@ -0,0 +1,26 @@
+extern crate prettytable;
+use prettytable::Table;
+
+/*
+ Following main function will print :
+ +---------+------+---------+
+ | ABC | DEFG | HIJKLMN |
+ +---------+------+---------+
+ | foobar | bar | foo |
+ +---------+------+---------+
+ | foobar2 | bar2 | foo2 |
+ +---------+------+---------+
+
+ ABC,DEFG,HIJKLMN
+ foobar,bar,foo
+ foobar2,bar2,foo2
+*/
+fn main() {
+ let table = Table::from_csv_string("ABC,DEFG,HIJKLMN\n\
+ foobar,bar,foo\n\
+ foobar2,bar2,foo2").unwrap();
+ table.printstd();
+
+ println!("");
+ println!("{}", table.to_csv(Vec::new()).unwrap().into_string());
+}
diff --git a/src/lib.rs b/src/lib.rs
index 0c477d1..0d2f756 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,14 +2,15 @@
extern crate unicode_width;
extern crate term;
extern crate atty;
+extern crate csv;
#[macro_use] extern crate lazy_static;
extern crate encode_unicode;
-use std::io;
-use std::io::{Write, Error};
+use std::io::{self, Read, Write, Error};
use std::fmt;
+use std::path::Path;
use std::iter::{FromIterator, IntoIterator};
-use std::slice::{Iter, IterMut};
+use std::slice::{Iter, IterMut};
use std::ops::{Index, IndexMut};
use std::mem::transmute;
@@ -179,6 +180,26 @@ impl <'a> TableSlice<'a> {
pub fn printstd(&self) {
self.print_tty(false);
}
+
+ /// Write the table to the specified writer.
+ pub fn to_csv<W: Write>(&self, w: W) -> csv::Result<csv::Writer<W>> {
+ self.to_csv_writer(csv::Writer::from_writer(w))
+ }
+
+ /// Write the table to the specified writer.
+ ///
+ /// This allows for format customisation.
+ pub fn to_csv_writer<W: Write>(&self, mut writer: csv::Writer<W>) -> csv::Result<csv::Writer<W>> {
+ for title in self.titles {
+ try!(writer.write(title.iter().map(|c| c.get_content())));
+ }
+ for row in self.rows {
+ try!(writer.write(row.iter().map(|c| c.get_content())));
+ }
+
+ try!(writer.flush());
+ Ok(writer)
+ }
}
impl <'a> IntoIterator for &'a TableSlice<'a> {
@@ -204,6 +225,25 @@ impl Table {
}
}
+ /// Create a table from a CSV string
+ ///
+ /// For more customisability use `from_csv()`
+ pub fn from_csv_string(csv_s: &str) -> csv::Result<Table> {
+ Ok(Table::from_csv(&mut csv::Reader::from_string(csv_s).has_headers(false)))
+ }
+
+ /// Create a table from a CSV file
+ ///
+ /// For more customisability use `from_csv()`
+ pub fn from_csv_file<P: AsRef<Path>>(csv_p: P) -> csv::Result<Table> {
+ Ok(Table::from_csv(&mut try!(csv::Reader::from_file(csv_p)).has_headers(false)))
+ }
+
+ /// Create a table from a CSV reader
+ pub fn from_csv<R: Read>(reader: &mut csv::Reader<R>) -> Table {
+ Table::init(reader.records().map(|row| Row::new(row.unwrap().into_iter().map(|cell| Cell::new(&cell)).collect())).collect())
+ }
+
/// Change the table format. Eg : Separators
pub fn set_format(&mut self, format: TableFormat) {
*self.format = format;
@@ -286,17 +326,17 @@ impl Table {
pub fn column_iter_mut(&mut self, column: usize) -> ColumnIterMut {
ColumnIterMut(self.rows.iter_mut(), column)
}
-
- /// Returns an iterator over immutable rows
- pub fn row_iter<'a>(&'a self) -> Iter<'a, Row> {
- self.rows.iter()
- }
-
- /// Returns an iterator over mutable rows
- pub fn row_iter_mut<'a>(&'a mut self) -> IterMut<'a, Row> {
- self.rows.iter_mut()
- }
-
+
+ /// Returns an iterator over immutable rows
+ pub fn row_iter<'a>(&'a self) -> Iter<'a, Row> {
+ self.rows.iter()
+ }
+
+ /// Returns an iterator over mutable rows
+ pub fn row_iter_mut<'a>(&'a mut self) -> IterMut<'a, Row> {
+ self.rows.iter_mut()
+ }
+
/// Print the table to `out`
pub fn print<T: Write+?Sized>(&self, out: &mut T) -> Result<(), Error> {
self.as_ref().print(out)
@@ -329,6 +369,18 @@ impl Table {
pub fn printstd(&self) {
self.as_ref().printstd();
}
+
+ /// Write the table to the specified writer.
+ pub fn to_csv<W: Write>(&self, w: W) -> csv::Result<csv::Writer<W>> {
+ self.as_ref().to_csv(w)
+ }
+
+ /// Write the table to the specified writer.
+ ///
+ /// This allows for format customisation.
+ pub fn to_csv_writer<W: Write>(&self, writer: csv::Writer<W>) -> csv::Result<csv::Writer<W>> {
+ self.as_ref().to_csv_writer(writer)
+ }
}
impl Index<usize> for Table {
@@ -615,7 +667,7 @@ mod tests {
assert_eq!(table[1][1].get_content(), "bc");
table[1][1] = Cell::new("newval");
- assert_eq!(table[1][1].get_content(), "newval");
+ assert_eq!(table[1][1].get_content(), "newval");
let out = "\
\u{0020}t1 t2 t3 \n\
@@ -686,4 +738,38 @@ mod tests {
println!("{}", table.to_string().replace("\r\n", "\n"));
assert_eq!(out, table.to_string().replace("\r\n", "\n"));
}
+
+ mod csv {
+ use Table;
+ use row::Row;
+ use cell::Cell;
+
+ static CSV_S: &'static str = "ABC,DEFG,HIJKLMN\n\
+ foobar,bar,foo\n\
+ foobar2,bar2,foo2\n";
+
+ fn test_table() -> Table {
+ let mut table = Table::new();
+ table.add_row(Row::new(vec![Cell::new("ABC"), Cell::new("DEFG"), Cell::new("HIJKLMN")]));
+ table.add_row(Row::new(vec![Cell::new("foobar"), Cell::new("bar"), Cell::new("foo")]));
+ table.add_row(Row::new(vec![Cell::new("foobar2"), Cell::new("bar2"), Cell::new("foo2")]));
+ table
+ }
+
+ #[test]
+ fn from() {
+ assert_eq!(test_table().to_string().replace("\r\n", "\n"), Table::from_csv_string(CSV_S).unwrap().to_string().replace("\r\n", "\n"));
+ }
+
+ #[test]
+ fn to() {
+ assert_eq!(test_table().to_csv(Vec::new()).unwrap().as_string(), CSV_S);
+ }
+
+ #[test]
+ fn trans() {
+ assert_eq!(Table::from_csv_string(test_table().to_csv(Vec::new()).unwrap().as_string()).unwrap().to_string().replace("\r\n", "\n"),
+ test_table().to_string().replace("\r\n", "\n"));
+ }
+ }
}