Giter Site home page Giter Site logo

zhiburt / tabled Goto Github PK

View Code? Open in Web Editor NEW
1.8K 11.0 71.0 46.64 MB

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

License: MIT License

Rust 99.99% Shell 0.01%
cli rust table pretty-print prettytable hacktoberfest table-generator

tabled's People

Contributors

andeya avatar brijeshkrishna avatar cgmossa avatar dandavison avatar danieleades avatar dependabot[bot] avatar fa993 avatar fn-bruce avatar isaaccloos avatar jondot avatar jvanbuel avatar kianmeng avatar kobzol avatar kozmod avatar michel-slm avatar mroci avatar nithinmuthukumar avatar nskobelevs avatar obi1kenobi avatar oliashish avatar panarch avatar pjhades avatar sd2k avatar senk8 avatar thomassimmer avatar vojta7 avatar wfxr avatar zhiburt avatar zjp-cn avatar zxch3n avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tabled's Issues

Fix `Panel` style rendering on tables with more than 2 columns

Running this code will result in the following.

use tabled::{Style, Table};

fn main() {
    let table = Table::new(&[(0, 1)])
        .with(tabled::Panel("Numbers", 0))
        .with(Style::modern());

    println!("{}", table);
}
┌───────────┬
│Numbers    │
├───────────┼
│ i32i32 │
├─────┼─────┤
│  01  │
└─────┴─────┘

As you may see the styles on the right side is not exactly correct.
It would be good to be fixed.

Provide a way to deal with types that don't implement Display

For instance:

#[derive(Tabled)]
pub struct MyRecord {
    pub id: i64,
    pub valid: Option<bool>
}

I can't implement Display for Option<bool>, so I'm stuck here ([E0117]: only traits defined in the current crate can be implemented for arbitrary types). I cannot use another type either.

Some possible ideas:

  • allow to switch to Debug instead of Display for the whole struct ?
  • same, on a per field basis ?
  • allow me to provide my own display trait, so I can implement it on arbitrary types ?

Using emojis breaks layout or panics

String length does not seem to be properly calculated when format strings contain emojis, leading to broken table layout or panic.

Sample code:

use tabled::{Tabled, table};

#[derive(Tabled)]
struct Language {
    name: &'static str,
    designed_by: &'static str,
    invented_year: usize,
}

fn main() {
    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
        },
    ];

    print!("{}", table!(&languages));
}

Crashes with:

thread 'main' panicked at 'index out of bounds: the len is 1 but the index is 1', /home/nicoulaj/.cargo/registry/src/github.com-1ecc6299db9ec823/papergrid-0.1.9/src/lib.rs:343:33
stack backtrace:
   0: rust_begin_unwind
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/std/src/panicking.rs:493:5
   1: core::panicking::panic_fmt
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/panicking.rs:92:14
   2: core::panicking::panic_bounds_check
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/panicking.rs:69:5
   3: <usize as core::slice::index::SliceIndex<[T]>>::index
             at /home/nicoulaj/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/index.rs:182:10
   4: core::slice::index::<impl core::ops::index::Index<I> for [T]>::index
             at /home/nicoulaj/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/index.rs:15:9
   5: <alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::index
             at /home/nicoulaj/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec/mod.rs:2381:9
   6: papergrid::Grid::build_row
             at /home/nicoulaj/.cargo/registry/src/github.com-1ecc6299db9ec823/papergrid-0.1.9/src/lib.rs:343:33
   7: <papergrid::Grid as core::fmt::Display>::fmt
             at /home/nicoulaj/.cargo/registry/src/github.com-1ecc6299db9ec823/papergrid-0.1.9/src/lib.rs:599:13
   8: <&T as core::fmt::Display>::fmt
             at /home/nicoulaj/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/mod.rs:2010:62
   9: core::fmt::write
             at /rustc/9bc8c42bb2f19e745a63f3445f1ac248fb015e53/library/core/src/fmt/mod.rs:1092:17
  10: core::fmt::Write::write_fmt
             at /home/nicoulaj/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/mod.rs:182:9
  11: <T as alloc::string::ToString>::to_string
             at /home/nicoulaj/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/string.rs:2270:9

Is it valuable to support ordering in derive macro?

We could support something like the following.

#[derive(Tabled)]
struct Picture {
  #[tabled(order = 2)];
  author: String,
  title: String,
  created_at_year: u32,
}

Which would result in a table where the author column would be the 2nd not the first like by default.

A use case I can picture is the type which is marked by #[repl(C)] probably.
But that's it.

Is it valuable?

tabled_derive v0.1.9 update introduced a semver-incompatible change

Now it implements the LENGTH associated constant which is missing from tabled v0.3.0. This results in broken builds for other projects (try cargo install cargo-bom). I'd suggest yanking tabled_derive v0.1.9 and releasing tabled_derive v0.2.0 with subsequent update to tabled.

is there a correct way to format `HashMap`

It is hard for me to understand how a HashMap could be made into a well-formatted
table. Can we start some discussion here? Because either it needs to be implemented or better
documented, so it is an issue regardless.

Create a Colored table?

We could create a method to output colored table.

The question only in which way we may colorize it.

Also ExtandedDisplay header pattern could be colorized. To bring more attention on separtion.

Add a support for colored borders and split lines

The goal is to be able to colorize borders.

It is also necessary to add a support for colored customization of a header

#[test]
#[cfg(feature = "color")]
fn top_border_override_with_colored_string_test() {
    use owo_colors::OwoColorize;

    let data = create_vector::<2, 2>();
    let table = Table::new(&data)
        .with(Style::ASCII)
        .with(TopBorderText::new("-Table".on_black().green().to_string()))
        .to_string();

    let expected = concat!(
        "\u{1b}[32m\u{1b}[40m-Table\u{1b}[0m\u{1b}[0m---------+----------+\n",
        "| N | column 0 | column 1 |\n",
        "+---+----------+----------+\n",
        "| 0 |   0-0    |   0-1    |\n",
        "+---+----------+----------+\n",
        "| 1 |   1-0    |   1-1    |\n",
        "+---+----------+----------+\n",
    );

    assert_eq!(table, expected);
}

Add an option to avoid line-breaking in the middle of a word

Currently I'm just putting some extra space in my strings so that the whole word gets wrapped to next line instead of line-wrapping in the middle of a word.

It would be cool to have an option to automatically line-wrap at word boundaries.

Add `AlignmentHorizontal::No` in order to not change the content and print it as it is

The name may be not perfect but the idea is to use string as it is.

Currently it's not possible to have a cell which starts from spaces.

Example:

#[test]
fn table_value_starts_with_spaces() {
    let expected = "+------+\n\
                    | i32  |\n\
                    +------+\n\
                    |    1 |\n\
                    +------+\n";

    let table = Table::new(&["   1"]).to_string();

    assert_eq!(table, expected);
}

The test will fail because by default we use HorizontalAlignment::Center

Add an option like `display_with` but only which takes a `&self`

It may be useful as sometimes we would like to print a content on the basis of some internal information not only on the type information itself.

#[derive(Tabled)]
struct House {
   #[field(display_with_self = "foo")]
   key: String,
}

fn foo(&House) -> String { ... }

Disable headers?

Thanks for making this beautiful crate ❤️ . I am very much enjoying working with it.

So, It there any way to disable/remove the headers completely. In my use case headers don't make that much sense.

For example, I am printing a table like this

  • Code
let details = [
    ("Username", "username"),
    ("Password", "password"),
    ("URL", "url"),
    ("Notes", "notes"),
];

let table = table!(
    &details,
    Style::PseudoClean,
    HorizontalAlignment::new(Alignment::Left, AlignmentObject::Full),
    ChangeRing(Row(1..), vec![Box::new(|s| format!(" {} ", s))])
);

println!("{}", table);
  • Output
┌──────────┬──────────┐
│&str      │&str      │
├──────────┼──────────┤
│ Username │ username │
│ Password │ password │
│ URL      │ url      │
│ Notes    │ notes    │
└──────────┴──────────┘
  • Wanted
┌──────────┬──────────┐
│ Username │ username │
│ Password │ password │
│ URL      │ url      │
│ Notes    │ notes    │
└──────────┴──────────┘

Maybe there is already a way to disable headers but I wasn't able to find it in the docs.

Unable to compile

I ran cargo upgrade and papergrid got updated to 0.1.11 and now I am unable to compile tabled because somehow papergrid contains a breaking change.

  • Error
error[E0432]: unresolved import `papergrid::Alignment`
 --> /home/hello/.cargo/registry/src/github.com-1ecc6299db9ec823/tabled-0.1.3/src/alignment.rs:1:17
  |
1 | use papergrid::{Alignment, Entity, Grid, Settings};
  |                 ^^^^^^^^^ no `Alignment` in the root

error[E0432]: unresolved import `papergrid::Alignment`
   --> /home/hello/.cargo/registry/src/github.com-1ecc6299db9ec823/tabled-0.1.3/src/lib.rs:141:9
    |
141 | pub use papergrid::Alignment;
    |         ^^^^^^^^^^^^^^^^^^^^ no `Alignment` in the root

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0432`.
error: could not compile `tabled`

To learn more, run the command again with --verbose.
  • Crates details
tabled: "0.1.3"

# These are inside Cargo.lock
tabled_derive: "0.1.5"
papergrid: "0.1.11"

Add a `join` method

let table3 = table1.join(table2);

Notes:

  • ? Add an optional argument to define which stylies must be used
  • ? Add options to determine how to act if one table have a different amount of rows then the other

Why not insert a method to change the headers ?

Hello everyone, my use-case is to map a lot of different struct in one struct that implement the tabled trait; my problem is that I cannot easily change the headers since every struct need different header names.

Now I have this structure:
println!("{}", Table::new(testtable).to_string());

but I need something similar to this (the headers object could be a Vec of String):
println!("{}", Table::new(testtable).with_headers(headers).to_string());

is anyone interested in implement this ?

Create a style from pattern

We could create a style from pattern.

Like having a pattern for line.
And repeat it corresponding of table length.

I am note sure now how it may look like but here's a general idea.

PatternStyle::new("=+")

=+=+=+=+=
* 1  23 *
=+=+=+=+=

originally seen this approach here https://github.com/Nukesor/comfy-table

Add option to wrap when `MaxWidth` is configured

It would be really nice to be able to wrap wide columns onto newlines, rather than truncating them. Something like:

    let expected = concat!(
        "| id | destribution |    link    |\n",
        "|----+--------------+------------|\n",
        "| 0  |    Fedora    | https://ge |\n",
        "|    |              | tfedora.or |\n",
        "|    |              |     g/     |\n",
        "| 2  |   OpenSUSE   | https://ww |\n",
        "|    |              | w.opensuse |\n",
        "|    |              |   .org/    |\n",
        "| 3  |  Endeavouro  | https://en |\n",
        "|    |      s       | deavouros. |\n",
        "|    |              |    com/    |\n",
    );

when the max width is set to 10.


I had a go at this, and have the above test passing, but it required changing the public API of MaxWidth and didn't work great with type inference. Happy to push it up so you can take a look though.

Fix `Panel` rendering when it 2 `Panel`s are used

This is an example

use tabled::{Footer, Header, MaxWidth, Modify, Row, Style, Cell};

fn main() {
    let message = r#"The terms "the ocean" or "the sea" used without specification refer to the interconnected body of salt water covering the majority of the Earth's surface"#;
    let link = r#"https://en.wikipedia.org/wiki/Ocean"#;

    let oceans = ["Atlantic", "Pacific", "Indian", "Southern", "Arctic"];

    let mut builder = tabled::builder::Builder::default().set_header(["#", "Ocean"]);
    for (i, ocean) in oceans.iter().enumerate() {
        builder = builder.add_row([i.to_string(), ocean.to_string()]);
    }

    let table = builder
        .build()
        .with(Header(message))
        .with(Footer(link))
        .with(Modify::new(Cell(0, 0)).with(MaxWidth::wrapping(5)))
        .with(Style::GITHUB_MARKDOWN);

    println!("{}", table);
}
|The t         |
|erms          |
|"the          |
|--------------+
|      #       |       Ocean        |

Recognize formatting options in Display implementation

std::fmt::Formatter has a bunch of options which can be determined.
We could change the table according to these options.

The changes may be done here.

tabled/src/lib.rs

Lines 304 to 308 in 0dbb426

impl fmt::Display for Table {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.grid)
}
}

  • align
    Align could apply an Alignment for each cell.
  • width
    Width ideally would need to set a width of the whole table including length of separators.
    But it's not clear then how to behave in cases where minimum possible length is 5 but 3 was specified.
    Print nothing?

There's more options out there but I don't see there use case yet.
But it might be there.

Hyperlinks break width detection

Following instructions in this gist, the way to print a hyperlink in the terminal with rust is something like format!("\x1b]8;;{}\x1b\\{}\x1b]8;;\x1b\\", display, url) which displays in the terminal as having width display.len(), but tabled appears to think its display width is approximately 14+display.len()+url.len(). This and others are listed in the operating system command section of the relevant wikipedia page.

An example of the results

┌─────────────────────────────────────────────────────────────────────────────┬────────────────────┐
│                                    name                                     │     similarity     │
├─────────────────────────────────────────────────────────────────────────────┼────────────────────┤
│ Person1 │        100         │
│         Person2         │ 65.38461538461539  │
│      Person3      │ 62.962962962962955 │
│    Person4    │ 62.962962962962955 │
│       Person5       │ 60.714285714285715 │
└─────────────────────────────────────────────────────────────────────────────┴────────────────────┘

after glancing at some docs, I think the underlying issue is with ansi-parser

Add a way to print a list of tables in line

I noticed that there's no easy way to print 2 tables in a row.
Like this

┌───────────────┬─────────┬──────────┬───────────┐        ┌───────────────┬─────────┬──────────┬───────────┐
│ temperature_c │ wind_ms │ latitude │ longitude │        │ temperature_c │ wind_ms │ latitude │ longitude │
├───────────────┼─────────┼──────────┼───────────┤        ├───────────────┼─────────┼──────────┼───────────┤
│      16       │  3000   │ 111.111  │  333.333  │        │      16       │  3000   │ 111.111  │  333.333  │
│      -20      │   300   │  5.111   │  7282.1   │        │      -20      │   300   │  5.111   │  7282.1   │ 
│      40       │   100   │    0     │     0     │        │      40       │   100   │    0     │     0     │
└───────────────┴─────────┴──────────┴───────────┘        └───────────────┴─────────┴──────────┴───────────┘

We could create a different type for achieving it.

Or we could create a type which implements Tabled and wraps Table.
So essentially a 2 tables inside 1 would be printed.
Like this

let line = Table::new([ table1, table2 ])

Actually it will not work because Table::new takes rows not columns

If anyone have an idea according to the design please feel free to discuss.

Create `MinWidth` component

MinWidth constrain cells to the given width if they have not meet a necessary length.

An example

#[test]
fn min_width() {
    let data = create_vector::<3, 3>();
    let table = Table::new(&data)
        .with(Style::GITHUB_MARKDOWN)
        .with(Modify::new(Column(..1)).with(MinWidth(5)))
        .to_string();

    let expected = concat!(
        "|  N  | column 0 |\n",
        "|-----+----------|\n",
        "|  0  |   0-1    |\n",
        "|  1  |   1-1    |\n",
        "|  2  |   2-1    |\n",
    );

    assert_eq!(table, expected);
}

It's necessary to determine what is the proper behavior in case it's used together with MaxWidth.
And if these are needed to be combined as 1 type Width.

An implementation can be inspired by MaxWidth component.
But I would change the actually content via format by adding the necessary amount of spaces.
A space character may worth to be a constant.

Allow completely custom border

It could be cool to have an ability to have a completely custom border with text squeezed in etc.

Example

---Hello World---
...

colided `span`ed columns cause incorrect rendering

It doesn't affect tabled but it must be resolved to have the same algorithm for tabled::Panel in #77.
*Actually not for #77 but for exposure of #71 certainly

The correct view is not defined yet.
But the below test shows an issue.

#[test]
fn render_2_colided_row_span_3x3() {
    let mut grid = Grid::new(3, 3);
    grid.set_cell_borders(DEFAULT_CELL_STYLE.clone());

    grid.set(&Entity::Cell(0, 0), Settings::new().text("0-01111111").span(2));
    grid.set(&Entity::Cell(1, 0), Settings::new().text("1-0"));
    grid.set(&Entity::Cell(1, 1), Settings::new().text("1-1").span(2));
    grid.set(&Entity::Cell(1, 2), Settings::new().text("1-1").span(0));
    grid.set(&Entity::Cell(2, 0), Settings::new().text("2-0"));
    grid.set(&Entity::Cell(2, 1), Settings::new().text("2-1"));
    grid.set(&Entity::Cell(2, 2), Settings::new().text("2-2"));

    let grid = grid.to_string();

    let expected = concat!(
        "+---+------+---+\n",
        "|0-01111111|   |\n",
        "+---+------+---+\n",
        "|1-0|1-1       |\n",
        "+---+------+---+\n",
        "|2-0|  2-1 |2-2|\n",
        "+---+------+---+\n",
    );

    println!("{}", grid);

    assert_eq!(grid, expected);

    let mut grid = Grid::new(3, 3);
    grid.set_cell_borders(DEFAULT_CELL_STYLE.clone());

    grid.set(&Entity::Cell(0, 0), Settings::new().text("0-0").span(2));
    grid.set(&Entity::Cell(1, 0), Settings::new().text("1-0"));
    grid.set(&Entity::Cell(1, 1), Settings::new().text("1-11111111").span(2));
    grid.set(&Entity::Cell(1, 2), Settings::new().text("1-1").span(0));
    grid.set(&Entity::Cell(2, 0), Settings::new().text("2-0"));
    grid.set(&Entity::Cell(2, 1), Settings::new().text("2-1"));
    grid.set(&Entity::Cell(2, 2), Settings::new().text("2-2"));

    let grid = grid.to_string();


    let expected = concat!(
        "+---+------+---+\n",
        "|0-0       |   |\n",
        "+---+------+---+\n",
        "|1-0|1-11111111|\n",
        "+---+------+---+\n",
        "|2-0|  2-1 |2-2|\n",
        "+---+------+---+\n",
    );


    println!("{}", grid);

    assert_eq!(grid, expected);
}

Support psql-like 'expanded display'

psql has an 'expanded display' mode, which converts the format to two columns, with the header in the first column and value in the second, and one row printed at a time:

peter@localhost testdb=> \a \t \x
Output format is aligned.
Tuples only is off.
Expanded display is on.
peter@localhost testdb=> SELECT * FROM my_table;
-[ RECORD 1 ]-
first  | 1
second | one
-[ RECORD 2 ]-
first  | 2
second | two
-[ RECORD 3 ]-
first  | 3
second | three
-[ RECORD 4 ]-
first  | 4
second | four

(example taken from the bottom of https://www.postgresql.org/docs/current/app-psql.html).

It would be great if something similar could be supported by this crate, as it helps a lot when rows have so many columns that they span multiple lines.

Thanks for the crate by the way, it's working wonderfully!

Add a `Margin` modifier

Margins

Margins can be set outside the grid (top, bottom, left, right). Margins and the character used for rendering the margin can be set separately.

vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
>>>┌───────────┬───────────┐<<<<
>>>│row 1 col 1│row 1 col 2│<<<<
>>>├───────────┼───────────┤<<<<
>>>│row 2 col 1│row 2 col 2│<<<<
>>>└───────────┴───────────┘<<<<
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

There's a list of steps necessary to take.

  • A new margin field must be added to papergrid::Grid.
  • fmt::Display of papergrid::Grid must be updated.
  • margin.rs with Margin modifier must be created in tabled which will set the table margin.

The possible implementation of tabled::Margin

struct Margin {
  top: Option<Indent>,
  bottom: Option<Indent>,
  left: Option<Indent>,
  right: Option<Indent>,
}

struct Indent {
  size: usize,
  symbol: char,
}

Inspired by the same functionality in https://github.com/vdmeer/asciitable

How to set table width to be terminal width

Hi, I'm experimenting with this library, and I'm wondering if it's possible to set the table width automatically so that it's the same as the terminal's width. I can get the terminal width using the terminal_size crate or similar, but I'm unsure how to do actually use that to configure the table. This would be very useful for me if possible. Thanks!

Add new styles

I am not sure what the appropriate names for these styles.
Please be free to chose the name for it.

To create a style is necessary to create a new constant and function in style.rs file.
Look at the existing styles.

tabled/src/style.rs

Lines 210 to 220 in 6aa713c

const _ASCII: StyleSettings = StyleSettings::new(
Frame {
bottom: Some(Line::bordered('-', '+', '+', '+')),
top: Some(Line::bordered('-', '+', '+', '+')),
left: Some('|'),
right: Some('|'),
},
Some(Line::bordered('-', '+', '+', '+')),
Some(Line::bordered('-', '+', '+', '+')),
Some('|'),
);

Bellow there's a list of styles which could be added.

┌           ┐
 rc 11 rc 12

 rc 21 rc 22 
└           ┘
┌           ┐
 rc 11 rc 12
├     ┼     ┤       
 rc 21 rc 22  
└           ┘
rc 11│rc 12
─────┼─────
rc 21│rc 22
│rc 11 rc 12 
│
│rc 21 rc 22 

Inspired by the same functionality in https://github.com/vdmeer/asciitable

Add an option to set the character for the padding

Currently the default character we use is a space character .

The idea is to set this character to a custom character.

let indent = tabled::Indent::new(0, 0, 1, 1).set_padding_char('V', '^', '<', '>');
│vvvvvvvvvvvvvvv│vvvvvvvvvvvvvvv│
│> row 1 col 1 <│> row 1 col 2 <│
│^^^^^^^^^^^^^^^│^^^^^^^^^^^^^^^│

The name of the function is not perfect.
Please if you have a better idea use it.

The changes must be done in Indent structure and in papergrid::Settings.


inspired by the same logic in https://github.com/vdmeer/asciitable

Add a trait for `table()` on `Iterator`

It seems possible to create a trait which would be implemented for any Iterator.
So the following calls could be done.

let people: &[Person] = ...
let table = people.table()
                  .with(Style::psql());
let people: Vec<Person> = ...
let table = people.table()
                  .with(Style::psql());

Is it seem like a good idea?

The idea of implementation can be taken from https://youtu.be/bnnacleqg6k

Support table name in derive

The idea is that we could set a table name on a type derived with Tabled

#[derive(Tabled)
#[tabled(name = "Users")]
struct User {
  id: i64,
  surname: String,
  lastname: String,
}

Using such a type would build a header with a table name.
Which may look like the following.

┌───────────────────────────┬
│           Users           │
├───────────────────────────┼
│ id │ surname   │ lastname │
             ....
└────┴───────────┴──────────┘

It requires changes in Tabled trait.
Which I would not do.

Probably a different trait will must to be created.
Which would extend a Tabled trait and would have a default implementation for type implements it.

The name of argument #[tabled] may be not ideal though.

Hidden fields shouldn't need to implement Display

I have a field of a struct which I do not plan to show in the table output. However, despite adding:

    #[header(hidden = true)]
    foo: SomeType

I still have an error compiling the struct, saying SomeType doesn't implement display. Obviously, I don't want to go through the trouble of implementing Display for a type I don't plan to list in the table. If possible, there should be a way to completely disable parsing for this field so that not having Display implemented for a field which is hidden doesn't error out.

Color rendering error

Cargo.toml:

[dependencies]
colored = "2.0.0"
[dependencies.tabled]
version = "0.3.0"
default-features = false
features = ["color"]

main.rs

use colored::Colorize;
use tabled::{Column, Format, Full, MaxWidth, Modify, Style, Table, Tabled};

#[derive(Tabled)]
struct Language {
    name: &'static str,
    designed_by: &'static str,
    invented_year: usize,
}

impl Language {
    fn new(name: &'static str, designed_by: &'static str, invented_year: usize) -> Self {
        Self {
            name,
            designed_by,
            invented_year,
        }
    }
}

fn main() {
    let languages = vec![
        Language::new("C 💕", "Dennis  Ritchie", 1972),
        Language::new("Rust 👍", "Graydon Hoare", 2010),
        Language::new("Go", "Pob Pike", 2009),
    ];

    let table = Table::new(languages)
        .with(Modify::new(Full).with(MaxWidth::wrapping(8)))
        .with(Modify::new(Column(..1)).with(Format(|s| s.red().to_string())))
        .with(Modify::new(Column(1..2)).with(Format(|s| s.green().to_string())))
        .with(Modify::new(Column(2..)).with(Format(|s| s.blue().to_string())))
        .with(Style::pseudo());
    println!("{}", table);
}

2021-10-18 11 28 37

Why is "_by" blue and not green?

Also, why is "Ritchie" white and not green?

2021-10-18 11 29 35

I used a small terminal, so I limited the width of the table.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.