1#![warn(missing_docs,
2 unused_extern_crates,
3 unused_import_braces,
4 unused_qualifications)]
5extern crate unicode_width;
7extern crate term;
8extern crate atty;
9#[macro_use]
10extern crate lazy_static;
11extern crate encode_unicode;
12
13use std::io::{self, Write, Error};
14use std::fmt;
15use std::iter::{FromIterator, IntoIterator};
16use std::slice::{Iter, IterMut};
17use std::ops::{Index, IndexMut};
18use std::mem::transmute;
19
20pub use term::{Attr, color};
21pub(crate) use term::{Terminal, stdout};
22
23mod cell;
24mod row;
25pub mod format;
26mod utils;
27
28#[cfg(feature = "csv")]
29pub mod csv;
30
31pub use row::Row;
32pub use cell::Cell;
33use format::{TableFormat, LinePosition, consts};
34use utils::StringWriter;
35
36#[derive(Clone, Debug, Hash, PartialEq, Eq)]
38pub struct Table {
39 format: Box<TableFormat>,
40 titles: Box<Option<Row>>,
41 rows: Vec<Row>,
42}
43
44#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
64pub struct TableSlice<'a> {
65 format: &'a TableFormat,
66 titles: &'a Option<Row>,
67 rows: &'a [Row],
68}
69
70impl<'a> TableSlice<'a> {
71 #[deprecated(since="0.8.0", note="Will become private in future release. See [issue #87](https://github.com/phsym/prettytable-rs/issues/87)")]
73 pub fn get_column_num(&self) -> usize {
74 let mut cnum = 0;
75 for r in self.rows {
76 let l = r.column_count();
77 if l > cnum {
78 cnum = l;
79 }
80 }
81 cnum
82 }
83
84 pub fn len(&self) -> usize {
86 self.rows.len()
87 }
88
89 pub fn is_empty(&self) -> bool {
91 self.rows.is_empty()
92 }
93
94 pub fn get_row(&self, row: usize) -> Option<&Row> {
96 self.rows.get(row)
97 }
98
99 fn get_column_width(&self, col_idx: usize) -> usize {
102 let mut width = match *self.titles {
103 Some(ref t) => t.get_column_width(col_idx, self.format),
104 None => 0,
105 };
106 for r in self.rows {
107 let l = r.get_column_width(col_idx, self.format);
108 if l > width {
109 width = l;
110 }
111 }
112 width
113 }
114
115 fn get_all_column_width(&self) -> Vec<usize> {
118 let colnum = self.get_column_num();
119 let mut col_width = vec![0usize; colnum];
120 for i in 0..colnum {
121 col_width[i] = self.get_column_width(i);
123 }
124 col_width
125 }
126
127 pub fn column_iter(&self, column: usize) -> ColumnIter {
129 ColumnIter(self.rows.iter(), column)
130 }
131
132 pub fn row_iter(&self) -> Iter<Row> {
134 self.rows.iter()
135 }
136
137 fn __print<T: Write + ?Sized, F>(&self, out: &mut T, f: F) -> Result<usize, Error>
139 where F: Fn(&Row, &mut T, &TableFormat, &[usize]) -> Result<usize, Error>
140 {
141 let mut height = 0;
142 let col_width = self.get_all_column_width();
144 height += self.format
145 .print_line_separator(out, &col_width, LinePosition::Top)?;
146 if let Some(ref t) = *self.titles {
147 height += f(t, out, self.format, &col_width)?;
148 height += self.format
149 .print_line_separator(out, &col_width, LinePosition::Title)?;
150 }
151 let mut iter = self.rows.into_iter().peekable();
153 while let Some(r) = iter.next() {
154 height += f(r, out, self.format, &col_width)?;
155 if iter.peek().is_some() {
156 height += self.format
157 .print_line_separator(out, &col_width, LinePosition::Intern)?;
158 }
159 }
160 height += self.format
161 .print_line_separator(out, &col_width, LinePosition::Bottom)?;
162 out.flush()?;
163 Ok(height)
164 }
165
166 pub fn print<T: Write + ?Sized>(&self, out: &mut T) -> Result<usize, Error> {
169 self.__print(out, Row::print)
170 }
171
172 pub fn print_term<T: Terminal + ?Sized>(&self, out: &mut T) -> Result<usize, Error> {
175 self.__print(out, Row::print_term)
176 }
177
178 pub fn print_tty(&self, force_colorize: bool) -> usize {
189 let r = match (stdout(), atty::is(atty::Stream::Stdout) || force_colorize) {
190 (Some(mut o), true) => self.print_term(&mut *o),
191 _ => self.print(&mut io::stdout()),
192 };
193 match r {
194 Err(e) => panic!("Cannot print table to standard output : {}", e),
195 Ok(height) => height
196 }
197 }
198
199 pub fn printstd(&self) -> usize {
209 self.print_tty(false)
210 }
211}
212
213impl<'a> IntoIterator for &'a TableSlice<'a> {
214 type Item = &'a Row;
215 type IntoIter = Iter<'a, Row>;
216 fn into_iter(self) -> Self::IntoIter {
217 self.row_iter()
218 }
219}
220
221impl Table {
222 pub fn new() -> Table {
224 Self::init(Vec::new())
225 }
226
227 pub fn init(rows: Vec<Row>) -> Table {
229 Table {
230 rows: rows,
231 titles: Box::new(None),
232 format: Box::new(*consts::FORMAT_DEFAULT),
233 }
234 }
235
236 pub fn set_format(&mut self, format: TableFormat) {
238 *self.format = format;
239 }
240
241 pub fn get_format(&mut self) -> &mut TableFormat {
243 &mut self.format
244 }
245
246 #[deprecated(since="0.8.0", note="Will become private in future release. See [issue #87](https://github.com/phsym/prettytable-rs/issues/87)")]
248 pub fn get_column_num(&self) -> usize {
249 self.as_slice().get_column_num()
250 }
251
252 pub fn len(&self) -> usize {
254 self.rows.len()
255 }
256
257 pub fn is_empty(&self) -> bool {
259 self.rows.is_empty()
260 }
261
262 pub fn set_titles(&mut self, titles: Row) {
264 *self.titles = Some(titles);
265 }
266
267 pub fn unset_titles(&mut self) {
269 *self.titles = None;
270 }
271
272 pub fn get_mut_row(&mut self, row: usize) -> Option<&mut Row> {
274 self.rows.get_mut(row)
275 }
276
277 pub fn get_row(&self, row: usize) -> Option<&Row> {
279 self.rows.get(row)
280 }
281
282 pub fn add_row(&mut self, row: Row) -> &mut Row {
285 self.rows.push(row);
286 let l = self.rows.len() - 1;
287 &mut self.rows[l]
288 }
289
290 pub fn add_empty_row(&mut self) -> &mut Row {
292 self.add_row(Row::default())
293 }
294
295 pub fn insert_row(&mut self, index: usize, row: Row) -> &mut Row {
298 if index < self.rows.len() {
299 self.rows.insert(index, row);
300 &mut self.rows[index]
301 } else {
302 self.add_row(row)
303 }
304 }
305
306 pub fn set_element(&mut self, element: &str, column: usize, row: usize) -> Result<(), &str> {
308 let rowline = self.get_mut_row(row).ok_or("Cannot find row")?;
309 rowline.set_cell(Cell::new(element), column)
311 }
312
313 pub fn remove_row(&mut self, index: usize) {
315 if index < self.rows.len() {
316 self.rows.remove(index);
317 }
318 }
319
320 pub fn column_iter(&self, column: usize) -> ColumnIter {
322 ColumnIter(self.rows.iter(), column)
323 }
324
325 pub fn column_iter_mut(&mut self, column: usize) -> ColumnIterMut {
327 ColumnIterMut(self.rows.iter_mut(), column)
328 }
329
330 pub fn row_iter(&self) -> Iter<Row> {
332 self.rows.iter()
333 }
334
335 pub fn row_iter_mut(&mut self) -> IterMut<Row> {
337 self.rows.iter_mut()
338 }
339
340 pub fn print<T: Write + ?Sized>(&self, out: &mut T) -> Result<usize, Error> {
343 self.as_slice().print(out)
344 }
345
346 pub fn print_term<T: Terminal + ?Sized>(&self, out: &mut T) -> Result<usize, Error> {
349 self.as_slice().print_term(out)
350 }
351
352 pub fn print_tty(&self, force_colorize: bool) -> usize {
363 self.as_slice().print_tty(force_colorize)
364 }
365
366 pub fn printstd(&self) -> usize {
376 self.as_slice().printstd()
377 }
378
379}
380
381trait AsTableSlice {
382 fn as_slice(&self) -> TableSlice<'_> ;
383}
384
385impl AsTableSlice for Table {
386 fn as_slice(&self) -> TableSlice<'_> {
387 TableSlice { format: &self.format, titles: &self.titles, rows: &self.rows }
388 }
389}
390
391impl <T> AsTableSlice for T where T: AsRef<Table> {
392 fn as_slice(&self) -> TableSlice<'_> {
393 self.as_ref().as_slice()
394 }
395}
396
397impl Index<usize> for Table {
398 type Output = Row;
399 fn index(&self, idx: usize) -> &Self::Output {
400 &self.rows[idx]
401 }
402}
403
404impl<'a> Index<usize> for TableSlice<'a> {
405 type Output = Row;
406 fn index(&self, idx: usize) -> &Self::Output {
407 &self.rows[idx]
408 }
409}
410
411impl IndexMut<usize> for Table {
412 fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
413 &mut self.rows[idx]
414 }
415}
416
417impl fmt::Display for Table {
418 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
419 self.as_slice().fmt(fmt)
420 }
421}
422
423impl<'a> fmt::Display for TableSlice<'a> {
424 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
425 let mut writer = StringWriter::new();
426 if self.print(&mut writer).is_err() {
427 return Err(fmt::Error);
428 }
429 fmt.write_str(writer.as_string())
430 }
431}
432
433impl<B: ToString, A: IntoIterator<Item = B>> FromIterator<A> for Table {
434 fn from_iter<T>(iterator: T) -> Table
435 where T: IntoIterator<Item = A>
436 {
437 Self::init(iterator.into_iter().map(Row::from).collect())
438 }
439}
440
441impl FromIterator<Row> for Table {
442 fn from_iter<T>(iterator: T) -> Table
443 where T: IntoIterator<Item = Row>
444 {
445 Self::init(iterator.into_iter().collect())
446 }
447}
448
449impl<T, A, B> From<T> for Table
450 where B: ToString,
451 A: IntoIterator<Item = B>,
452 T: IntoIterator<Item = A>
453{
454 fn from(it: T) -> Table {
455 Self::from_iter(it)
456 }
457}
458
459impl<'a> IntoIterator for &'a Table {
460 type Item = &'a Row;
461 type IntoIter = Iter<'a, Row>;
462 fn into_iter(self) -> Self::IntoIter {
463 self.row_iter()
464 }
465}
466
467impl<'a> IntoIterator for &'a mut Table {
468 type Item = &'a mut Row;
469 type IntoIter = IterMut<'a, Row>;
470 fn into_iter(self) -> Self::IntoIter {
471 self.row_iter_mut()
472 }
473}
474
475impl <A: Into<Row>> Extend<A> for Table {
484 fn extend<T: IntoIterator<Item=A>>(&mut self, iter: T) {
485 self.rows.extend(iter.into_iter().map(|r| r.into()));
486 }
487}
488
489pub struct ColumnIter<'a>(Iter<'a, Row>, usize);
491
492impl<'a> Iterator for ColumnIter<'a> {
493 type Item = &'a Cell;
494 fn next(&mut self) -> Option<&'a Cell> {
495 self.0.next().and_then(|row| row.get_cell(self.1))
496 }
497}
498
499pub struct ColumnIterMut<'a>(IterMut<'a, Row>, usize);
501
502impl<'a> Iterator for ColumnIterMut<'a> {
503 type Item = &'a mut Cell;
504 fn next(&mut self) -> Option<&'a mut Cell> {
505 self.0.next().and_then(|row| row.get_mut_cell(self.1))
506 }
507}
508
509impl <'a> AsTableSlice for TableSlice<'a> {
510 fn as_slice(&self) -> TableSlice<'_> {
511 *self
512 }
513}
514
515impl<'a> AsRef<TableSlice<'a>> for TableSlice<'a> {
516 fn as_ref(&self) -> &TableSlice<'a> {
517 self
518 }
519}
520
521pub trait Slice<'a, E> {
523 type Output: 'a;
525 fn slice(&'a self, arg: E) -> Self::Output;
527}
528
529impl<'a, T, E> Slice<'a, E> for T
530 where T: AsTableSlice,
531 [Row]: Index<E, Output = [Row]>
532{
533 type Output = TableSlice<'a>;
534 fn slice(&'a self, arg: E) -> Self::Output {
535 let mut sl = self.as_slice();
536 sl.rows = sl.rows.index(arg);
537 sl
538 }
539}
540
541#[macro_export]
577macro_rules! table {
578 ($([$($content:tt)*]), *) => (
579 $crate::Table::init(vec![$(row![$($content)*]), *])
580 );
581}
582
583#[macro_export]
587macro_rules! ptable {
588 ($($content:tt)*) => (
589 {
590 let tab = table!($($content)*);
591 tab.printstd();
592 tab
593 }
594 );
595}
596
597#[cfg(test)]
598mod tests {
599 use Table;
600 use Slice;
601 use Row;
602 use Cell;
603 use format;
604 use format::consts::{FORMAT_DEFAULT, FORMAT_NO_LINESEP, FORMAT_NO_COLSEP, FORMAT_CLEAN, FORMAT_BOX_CHARS};
605 use utils::StringWriter;
606
607 #[test]
608 fn table() {
609 let mut table = Table::new();
610 table.add_row(Row::new(vec![Cell::new("a"), Cell::new("bc"), Cell::new("def")]));
611 table.add_row(Row::new(vec![Cell::new("def"), Cell::new("bc"), Cell::new("a")]));
612 table.set_titles(Row::new(vec![Cell::new("t1"), Cell::new("t2"), Cell::new("t3")]));
613 let out = "\
614+-----+----+-----+
615| t1 | t2 | t3 |
616+=====+====+=====+
617| a | bc | def |
618+-----+----+-----+
619| def | bc | a |
620+-----+----+-----+
621";
622 assert_eq!(table.to_string().replace("\r\n", "\n"), out);
623 assert_eq!(7, table.print(&mut StringWriter::new()).unwrap());
624 table.unset_titles();
625 let out = "\
626+-----+----+-----+
627| a | bc | def |
628+-----+----+-----+
629| def | bc | a |
630+-----+----+-----+
631";
632 assert_eq!(table.to_string().replace("\r\n", "\n"), out);
633 assert_eq!(5, table.print(&mut StringWriter::new()).unwrap());
634 }
635
636 #[test]
637 fn index() {
638 let mut table = Table::new();
639 table.add_row(Row::new(vec![Cell::new("a"), Cell::new("bc"), Cell::new("def")]));
640 table.add_row(Row::new(vec![Cell::new("def"), Cell::new("bc"), Cell::new("a")]));
641 table.set_titles(Row::new(vec![Cell::new("t1"), Cell::new("t2"), Cell::new("t3")]));
642 assert_eq!(table[1][1].get_content(), "bc");
643
644 table[1][1] = Cell::new("newval");
645 assert_eq!(table[1][1].get_content(), "newval");
646
647 let out = "\
648+-----+--------+-----+
649| t1 | t2 | t3 |
650+=====+========+=====+
651| a | bc | def |
652+-----+--------+-----+
653| def | newval | a |
654+-----+--------+-----+
655";
656 assert_eq!(table.to_string().replace("\r\n", "\n"), out);
657 assert_eq!(7, table.print(&mut StringWriter::new()).unwrap());
658 }
659
660 #[test]
661 fn table_size() {
662 let mut table = Table::new();
663 assert!(table.is_empty());
664 assert!(table.as_ref().is_empty());
665 assert_eq!(table.len(), 0);
666 assert_eq!(table.as_ref().len(), 0);
667 assert_eq!(table.get_column_num(), 0);
668 assert_eq!(table.as_ref().get_column_num(), 0);
669 table.add_empty_row();
670 assert!(!table.is_empty());
671 assert!(!table.as_ref().is_empty());
672 assert_eq!(table.len(), 1);
673 assert_eq!(table.as_ref().len(), 1);
674 assert_eq!(table.get_column_num(), 0);
675 assert_eq!(table.as_ref().get_column_num(), 0);
676 table[0].add_cell(Cell::default());
677 assert_eq!(table.get_column_num(), 1);
678 assert_eq!(table.as_ref().get_column_num(), 1);
679 }
680
681 #[test]
682 fn get_row() {
683 let mut table = Table::new();
684 table.add_row(Row::new(vec![Cell::new("a"), Cell::new("bc"), Cell::new("def")]));
685 table.add_row(Row::new(vec![Cell::new("def"), Cell::new("bc"), Cell::new("a")]));
686 assert!(table.get_row(12).is_none());
687 assert!(table.get_row(1).is_some());
688 assert_eq!(table.get_row(1).unwrap()[0].get_content(), "def");
689 assert!(table.get_mut_row(12).is_none());
690 assert!(table.get_mut_row(1).is_some());
691 table.get_mut_row(1).unwrap().add_cell(Cell::new("z"));
692 assert_eq!(table.get_row(1).unwrap()[3].get_content(), "z");
693 }
694
695 #[test]
696 fn add_empty_row() {
697 let mut table = Table::new();
698 assert_eq!(table.len(), 0);
699 table.add_empty_row();
700 assert_eq!(table.len(), 1);
701 assert_eq!(table[0].len(), 0);
702 }
703
704 #[test]
705 fn remove_row() {
706 let mut table = Table::new();
707 table.add_row(Row::new(vec![Cell::new("a"), Cell::new("bc"), Cell::new("def")]));
708 table.add_row(Row::new(vec![Cell::new("def"), Cell::new("bc"), Cell::new("a")]));
709 table.remove_row(12);
710 assert_eq!(table.len(), 2);
711 table.remove_row(0);
712 assert_eq!(table.len(), 1);
713 assert_eq!(table[0][0].get_content(), "def");
714 }
715
716 #[test]
717 fn insert_row() {
718 let mut table = Table::new();
719 table.add_row(Row::new(vec![Cell::new("a"), Cell::new("bc"), Cell::new("def")]));
720 table.add_row(Row::new(vec![Cell::new("def"), Cell::new("bc"), Cell::new("a")]));
721 table.insert_row(12,
722 Row::new(vec![Cell::new("1"), Cell::new("2"), Cell::new("3")]));
723 assert_eq!(table.len(), 3);
724 assert_eq!(table[2][1].get_content(), "2");
725 table.insert_row(1,
726 Row::new(vec![Cell::new("3"), Cell::new("4"), Cell::new("5")]));
727 assert_eq!(table.len(), 4);
728 assert_eq!(table[1][1].get_content(), "4");
729 assert_eq!(table[2][1].get_content(), "bc");
730 }
731
732 #[test]
733 fn set_element() {
734 let mut table = Table::new();
735 table.add_row(Row::new(vec![Cell::new("a"), Cell::new("bc"), Cell::new("def")]));
736 table.add_row(Row::new(vec![Cell::new("def"), Cell::new("bc"), Cell::new("a")]));
737 assert!(table.set_element("foo", 12, 12).is_err());
738 assert!(table.set_element("foo", 1, 1).is_ok());
739 assert_eq!(table[1][1].get_content(), "foo");
740 }
741
742 #[test]
743 fn no_linesep() {
744 let mut table = Table::new();
745 table.set_format(*FORMAT_NO_LINESEP);
746 table.add_row(Row::new(vec![Cell::new("a"), Cell::new("bc"), Cell::new("def")]));
747 table.add_row(Row::new(vec![Cell::new("def"), Cell::new("bc"), Cell::new("a")]));
748 table.set_titles(Row::new(vec![Cell::new("t1"), Cell::new("t2"), Cell::new("t3")]));
749 assert_eq!(table[1][1].get_content(), "bc");
750
751 table[1][1] = Cell::new("newval");
752 assert_eq!(table[1][1].get_content(), "newval");
753
754 let out = "\
755+-----+--------+-----+
756| t1 | t2 | t3 |
757| a | bc | def |
758| def | newval | a |
759+-----+--------+-----+
760";
761 assert_eq!(table.to_string().replace("\r\n", "\n"), out);
762 assert_eq!(5, table.print(&mut StringWriter::new()).unwrap());
763 }
764
765 #[test]
766 fn no_colsep() {
767 let mut table = Table::new();
768 table.set_format(*FORMAT_NO_COLSEP);
769 table.add_row(Row::new(vec![Cell::new("a"), Cell::new("bc"), Cell::new("def")]));
770 table.add_row(Row::new(vec![Cell::new("def"), Cell::new("bc"), Cell::new("a")]));
771 table.set_titles(Row::new(vec![Cell::new("t1"), Cell::new("t2"), Cell::new("t3")]));
772 assert_eq!(table[1][1].get_content(), "bc");
773
774 table[1][1] = Cell::new("newval");
775 assert_eq!(table[1][1].get_content(), "newval");
776
777 let out = "\
778------------------
779 t1 t2 t3 \n\
780==================
781 a bc def \n\
782------------------
783 def newval a \n\
784------------------
785";
786 println!("{}", out);
787 println!("____");
788 println!("{}", table.to_string().replace("\r\n", "\n"));
789 assert_eq!(table.to_string().replace("\r\n", "\n"), out);
790 assert_eq!(7, table.print(&mut StringWriter::new()).unwrap());
791 }
792
793 #[test]
794 fn clean() {
795 let mut table = Table::new();
796 table.set_format(*FORMAT_CLEAN);
797 table.add_row(Row::new(vec![Cell::new("a"), Cell::new("bc"), Cell::new("def")]));
798 table.add_row(Row::new(vec![Cell::new("def"), Cell::new("bc"), Cell::new("a")]));
799 table.set_titles(Row::new(vec![Cell::new("t1"), Cell::new("t2"), Cell::new("t3")]));
800 assert_eq!(table[1][1].get_content(), "bc");
801
802 table[1][1] = Cell::new("newval");
803 assert_eq!(table[1][1].get_content(), "newval");
804
805 let out = "\
806\u{0020}t1 t2 t3 \n\
807\u{0020}a bc def \n\
808\u{0020}def newval a \n\
809";
810 println!("{}", out);
811 println!("____");
812 println!("{}", table.to_string().replace("\r\n", "\n"));
813 assert_eq!(out, table.to_string().replace("\r\n", "\n"));
814 assert_eq!(3, table.print(&mut StringWriter::new()).unwrap());
815 }
816
817 #[test]
818 fn padding() {
819 let mut table = Table::new();
820 let mut format = *FORMAT_DEFAULT;
821 format.padding(2, 2);
822 table.set_format(format);
823 table.add_row(Row::new(vec![Cell::new("a"), Cell::new("bc"), Cell::new("def")]));
824 table.add_row(Row::new(vec![Cell::new("def"), Cell::new("bc"), Cell::new("a")]));
825 table.set_titles(Row::new(vec![Cell::new("t1"), Cell::new("t2"), Cell::new("t3")]));
826 assert_eq!(table[1][1].get_content(), "bc");
827
828 table[1][1] = Cell::new("newval");
829 assert_eq!(table[1][1].get_content(), "newval");
830
831 let out = "\
832+-------+----------+-------+
833| t1 | t2 | t3 |
834+=======+==========+=======+
835| a | bc | def |
836+-------+----------+-------+
837| def | newval | a |
838+-------+----------+-------+
839";
840 println!("{}", out);
841 println!("____");
842 println!("{}", table.to_string().replace("\r\n", "\n"));
843 assert_eq!(out, table.to_string().replace("\r\n", "\n"));
844 assert_eq!(7, table.print(&mut StringWriter::new()).unwrap());
845 }
846
847 #[test]
848 fn indent() {
849 let mut table = Table::new();
850 table.add_row(Row::new(vec![Cell::new("a"), Cell::new("bc"), Cell::new("def")]));
851 table.add_row(Row::new(vec![Cell::new("def"), Cell::new("bc"), Cell::new("a")]));
852 table.set_titles(Row::new(vec![Cell::new("t1"), Cell::new("t2"), Cell::new("t3")]));
853 table.get_format().indent(8);
854 let out = " +-----+----+-----+
855 | t1 | t2 | t3 |
856 +=====+====+=====+
857 | a | bc | def |
858 +-----+----+-----+
859 | def | bc | a |
860 +-----+----+-----+
861";
862 assert_eq!(table.to_string().replace("\r\n", "\n"), out);
863 assert_eq!(7, table.print(&mut StringWriter::new()).unwrap());
864 }
865
866 #[test]
867 fn slices() {
868 let mut table = Table::new();
869 table.set_titles(Row::new(vec![Cell::new("t1"), Cell::new("t2"), Cell::new("t3")]));
870 table.add_row(Row::new(vec![Cell::new("0"), Cell::new("0"), Cell::new("0")]));
871 table.add_row(Row::new(vec![Cell::new("1"), Cell::new("1"), Cell::new("1")]));
872 table.add_row(Row::new(vec![Cell::new("2"), Cell::new("2"), Cell::new("2")]));
873 table.add_row(Row::new(vec![Cell::new("3"), Cell::new("3"), Cell::new("3")]));
874 table.add_row(Row::new(vec![Cell::new("4"), Cell::new("4"), Cell::new("4")]));
875 table.add_row(Row::new(vec![Cell::new("5"), Cell::new("5"), Cell::new("5")]));
876 let out = "\
877+----+----+----+
878| t1 | t2 | t3 |
879+====+====+====+
880| 1 | 1 | 1 |
881+----+----+----+
882| 2 | 2 | 2 |
883+----+----+----+
884| 3 | 3 | 3 |
885+----+----+----+
886";
887 let slice = table.slice(..);
888 let slice = slice.slice(1..);
889 let slice = slice.slice(..3);
890 assert_eq!(out, slice.to_string().replace("\r\n", "\n"));
891 assert_eq!(9, slice.print(&mut StringWriter::new()).unwrap());
892 assert_eq!(out, table.slice(1..4).to_string().replace("\r\n", "\n"));
893 assert_eq!(9, table.slice(1..4).print(&mut StringWriter::new()).unwrap());
894 }
895
896 #[test]
897 fn test_unicode_separators() {
898 let mut table = Table::new();
899 table.set_format(*FORMAT_BOX_CHARS);
900 table.add_row(Row::new(vec![Cell::new("1"), Cell::new("1"), Cell::new("1")]));
901 table.add_row(Row::new(vec![Cell::new("2"), Cell::new("2"), Cell::new("2")]));
902 table.set_titles(Row::new(vec![Cell::new("t1"), Cell::new("t2"), Cell::new("t3")]));
903 let out = "\
904┌────┬────┬────┐
905│ t1 │ t2 │ t3 │
906├────┼────┼────┤
907│ 1 │ 1 │ 1 │
908├────┼────┼────┤
909│ 2 │ 2 │ 2 │
910└────┴────┴────┘
911";
912 println!("{}", out);
913 println!("____");
914 println!("{}", table.to_string().replace("\r\n", "\n"));
915 assert_eq!(out, table.to_string().replace("\r\n", "\n"));
916 assert_eq!(7, table.print(&mut StringWriter::new()).unwrap());
917 }
918
919 #[test]
920 fn test_readme_format() {
921
922 let mut table = Table::new();
925 let format = format::FormatBuilder::new()
926 .column_separator('|')
927 .borders('|')
928 .separators(&[format::LinePosition::Top,
929 format::LinePosition::Bottom],
930 format::LineSeparator::new('-', '+', '+', '+'))
931 .padding(1, 1)
932 .build();
933 table.set_format(format);
934
935 table.set_titles(Row::new(vec![Cell::new("Title 1"), Cell::new("Title 2")]));
936 table.add_row(Row::new(vec![Cell::new("Value 1"), Cell::new("Value 2")]));
937 table.add_row(Row::new(vec![Cell::new("Value three"), Cell::new("Value four")]));
938
939 let out = "\
940+-------------+------------+
941| Title 1 | Title 2 |
942| Value 1 | Value 2 |
943| Value three | Value four |
944+-------------+------------+
945";
946
947 println!("{}", out);
948 println!("____");
949 println!("{}", table.to_string().replace("\r\n","\n"));
950 assert_eq!(out, table.to_string().replace("\r\n","\n"));
951 assert_eq!(5, table.print(&mut StringWriter::new()).unwrap());
952 }
953
954 #[test]
955 fn test_readme_format_with_title() {
956 let mut table = Table::new();
957 table.set_format(*format::consts::FORMAT_NO_LINESEP_WITH_TITLE);
958
959 table.set_titles(Row::new(vec![Cell::new("Title 1"), Cell::new("Title 2")]));
960 table.add_row(Row::new(vec![Cell::new("Value 1"), Cell::new("Value 2")]));
961 table.add_row(Row::new(vec![Cell::new("Value three"), Cell::new("Value four")]));
962
963 let out = "\
964+-------------+------------+
965| Title 1 | Title 2 |
966+-------------+------------+
967| Value 1 | Value 2 |
968| Value three | Value four |
969+-------------+------------+
970";
971 println!("{}", out);
972 println!("____");
973 println!("{}", table.to_string().replace("\r\n","\n"));
974 assert_eq!(out, table.to_string().replace("\r\n","\n"));
975 assert_eq!(6, table.print(&mut StringWriter::new()).unwrap());
976 }
977
978 #[test]
979 fn test_horizontal_span() {
980 let mut table = Table::new();
981 table.set_titles(Row::new(vec![Cell::new("t1"), Cell::new("t2").with_hspan(2)]));
982 table.add_row(Row::new(vec![Cell::new("a"), Cell::new("bc"), Cell::new("def")]));
983 table.add_row(Row::new(vec![Cell::new("def").style_spec("H02c"), Cell::new("a")]));
984 let out = "\
985+----+----+-----+
986| t1 | t2 |
987+====+====+=====+
988| a | bc | def |
989+----+----+-----+
990| def | a |
991+----+----+-----+
992";
993 println!("{}", out);
994 println!("____");
995 println!("{}", table.to_string().replace("\r\n","\n"));
996 assert_eq!(out, table.to_string().replace("\r\n","\n"));
997 assert_eq!(7, table.print(&mut StringWriter::new()).unwrap());
998 }
999}