andeya / tabled

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

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

About

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

License:MIT License


Languages

Language:Rust 100.0%