tabled 0.1.3

An easy to use library for pretty print tables of Rust `struct`s and `enum`s.
Documentation

Build Status Coverage Status Crate docs.rs license dependency status

tabled

An easy to use library for pretty print tables of Rust structs and enums.

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() }),
);

carbon-2

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