tabled
An easy to use library for pretty print tables of Rust struct
s and enum
s.
Agenda
Usage
To print a list of structs or enums as a table.
Implement Tabled
trait for your struct/enum with or annotate it with a #[derive(Tabled)]
macro. Then call a table
macro.
use tabled::{Tabled, table};
#[derive(Tabled)]
struct Language {
name: &'static str,
designed_by: &'static str,
invented_year: usize,
}
let languages = vec![
Language{
name: "C",
designed_by: "Dennis Ritchie",
invented_year: 1972
},
Language{
name: "Rust",
designed_by: "Graydon Hoare",
invented_year: 2010
},
Language{
name: "Go",
designed_by: "Rob Pike",
invented_year: 2009
},
];
let table = table!(&languages);
let expected = "+------+----------------+---------------+\n\
| name | designed_by | invented_year |\n\
+------+----------------+---------------+\n\
| C | Dennis Ritchie | 1972 |\n\
+------+----------------+---------------+\n\
| Rust | Graydon Hoare | 2010 |\n\
+------+----------------+---------------+\n\
| Go | Rob Pike | 2009 |\n\
+------+----------------+---------------+\n";
assert_eq!(expected, table);
Derive information
To be able to use a Tabled
macro each field should implement std::fmt::Display
otherwise it will not work.
The following example will cause a error.
use tabled::Tabled;
#[derive(Tabled)]
struct SomeType {
field1: SomeOtherType,
}
struct SomeOtherType;
Most of the default types implements the trait out of the box.
use tabled::table;
let some_numbers = [1, 2, 3];
let table = table!(&some_numbers);
Style
Styles
A list of ready to use styles. A shocases for the data in the Usage section.
Styles can be chosen by passing a Style
argument like this to table!
macro.
let table = table!(&data, Style::psql());
Default
+------+----------------+---------------+
| name | designed_by | invented_year |
+------+----------------+---------------+
| C | Dennis Ritchie | 1972 |
+------+----------------+---------------+
| Rust | Graydon Hoare | 2010 |
+------+----------------+---------------+
| Go | Rob Pike | 2009 |
+------+----------------+---------------+
Psql
name | designed_by | invented_year
------+----------------+---------------
C | Dennis Ritchie | 1972
Rust | Graydon Hoare | 2010
Go | Rob Pike | 2009
GithubMarkdown
| name | designed_by | invented_year |
|------+----------------+---------------|
| C | Dennis Ritchie | 1972 |
| Rust | Graydon Hoare | 2010 |
| Go | Rob Pike | 2009 |
Pseudo
┌──────┬────────────────┬───────────────┐
│ name │ designed_by │ invented_year │
├──────┼────────────────┼───────────────┤
│ C │ Dennis Ritchie │ 1972 │
├──────┼────────────────┼───────────────┤
│ Rust │ Graydon Hoare │ 2010 │
├──────┼────────────────┼───────────────┤
│ Go │ Rob Pike │ 2009 │
└──────┴────────────────┴───────────────┘
PseudoClean
┌──────┬────────────────┬───────────────┐
│ name │ designed_by │ invented_year │
├──────┼────────────────┼───────────────┤
│ C │ Dennis Ritchie │ 1972 │
│ Rust │ Graydon Hoare │ 2010 │
│ Go │ Rob Pike │ 2009 │
└──────┴────────────────┴───────────────┘
Noborder
name designed_by invented_year
C Dennis Ritchie 1972
Rust Graydon Hoare 2010
Go Rob Pike 2009
Custom Style
You can modify existing styles to fits your needs.
table!(
&data,
tabled::Style::noborder()
.frame_bottom(Some(Line::short('*', ' '')))
.split(Some(Line::short(' ', ' ')))
.inner(' ')
)
Alignment
You can set a alignemt for a Header, Column, Row or All Cells.
table!(
&data,
Style::psql(),
HorizontalAlignment(Full, Alignment::Left)
);
Format
Format function provides an interface for a modification of cells.
let table = table!(
&data,
Style::psql(),
Format(Column(..), |s| { format!("<< {} >>", s) }),
Format(Row(..1), |s| { format!("Head {}", s) }),
);
Disable
You can remove a certain rows or column from the table.
table!(&data, Disable::Row(..1), Disable::Column(3..4));
Color
The library doesn't bind you in usage of any color library but to be able to work corectly with color input you should provide a --features color
.
The folowing change on the script in the usage and it's result
let table = table!(
&data,
Style::psql(),
Format(Column(..1), |s| { s.red().to_string() }),
Format(Column(1..2), |s| { s.blue().to_string() }),
Format(Column(2..), |s| { s.green().to_string() }),
);
Features
Column name override
You can use a #[header("")]
attribute to override a column name.
#[derive(Tabled)]
struct Person {
#[header("Name")]
first_name: &'static str,
#[header("Surname")]
last_name: &'static str,
}
Hide a column
You can mark filds as hidden in which case they fill be ignored and not be present on a sheet.
A similar affect could be achived by the means of a Disable
setting.
struct Person {
#[header(hidden = true)]
id: u8,
#[header("field 2", hidden)]
number: &'static str,
name: &'static str,
}
Tuple combination
You also can combine objets which implements Tabled
by means of tuples, you will get a combined columns of them.
use tabled::{Tabled, table, Style};
#[derive(Tabled)]
enum Domain {
Security,
Embeded,
Frontend,
Unknown,
}
#[derive(Tabled)]
struct Developer(#[header("name")] &'static str);
let data = vec![
(Developer("Terri Kshlerin"), Domain::Embeded),
(Developer("Catalina Dicki"), Domain::Security),
(Developer("Jennie Schmeler"), Domain::Frontend),
(Developer("Maxim Zhiburt"), Domain::Unknown),
];
let table = table!(data, Style::psql());
assert_eq!(
table,
concat!(
" name | Security | Embeded | Frontend | Unknown \n",
"-----------------+----------+---------+----------+---------\n",
" Terri Kshlerin | | + | | \n",
" Catalina Dicki | + | | | \n",
" Jennie Schmeler | | | + | \n",
" Maxim Zhiburt | | | | + \n"
)
);
Object
You can peak your target for settings using and
and not
methods for an object.
Full.not(Row(..1)) // peak all cells except header
Head.and(Column(..1)).not(Cell(0, 0)) // peak a header and first column except a (0, 0) cell