#table #terminal #unicode #bigtable

comfy-table

一个易于使用的库,用于构建带有自动内容包装的美丽表格

40 个版本 (稳定版)

7.1.1 2024年4月5日
7.1.0 2023年10月21日
7.0.1 2023年6月16日
6.2.0 2023年5月26日
0.1.0 2020年3月21日

#28 in 命令行界面

Download history 237046/week @ 2024-04-22 208589/week @ 2024-04-29 210168/week @ 2024-05-06 240904/week @ 2024-05-13 234609/week @ 2024-05-20 237916/week @ 2024-05-27 325000/week @ 2024-06-03 312488/week @ 2024-06-10 308535/week @ 2024-06-17 344020/week @ 2024-06-24 321819/week @ 2024-07-01 329117/week @ 2024-07-08 330074/week @ 2024-07-15 348524/week @ 2024-07-22 347868/week @ 2024-07-29 340046/week @ 2024-08-05

1,378,373 每月下载量
用于 539 个crate (203 直接)

MIT 许可证

155KB
2K SLoC

Comfy-table

GitHub Actions Workflow docs license Crates.io codecov

comfy-table

Comfy-table 被设计为一个易于使用的库,用于构建美观的终端表格。

目录

功能

  • 根据给定宽度动态排列内容。
  • 适用于终端的ANSI内容样式(颜色、粗体、闪烁等)。
  • 提供样式预设和预设修改器以供您开始。
  • 几乎可以自定义表格的每个部分(边框、行、填充、对齐)。
  • 对列的限制允许您对内容的排列方式有更多控制。
  • 跨平台(Linux、macOS、Windows)。
  • 它足够快。
    • 基准测试表明,一个具有复杂约束的相当大的表格在 470μs~0.5ms 内构建。
    • 文档顶部的表格需要 ~30μs
    • 这些数字来自一个超频的 i7-8700K,其单核最大性能为 4.9GHz。
    • 要运行自己的基准测试,请通过 cargo install cargo-criterion 安装 criterion,然后运行 cargo criterion

Comfy-table是用当前的 stable Rust 版本编写的。较旧的 Rust 版本可能可以工作,但不受官方支持。

示例

use comfy_table::Table;

fn main() {
    let mut table = Table::new();
    table
        .set_header(vec!["Header1", "Header2", "Header3"])
        .add_row(vec![
            "This is a text",
            "This is another text",
            "This is the third text",
        ])
        .add_row(vec![
            "This is another text",
            "Now\nadd some\nmulti line stuff",
            "This is awesome",
        ]);

    println!("{table}");
}

创建一个非常基本的表格。
这个表格将变得与您的内容一样宽。这里没有任何特别之处。

+----------------------+----------------------+------------------------+
| Header1              | Header2              | Header3                |
+======================================================================+
| This is a text       | This is another text | This is the third text |
|----------------------+----------------------+------------------------|
| This is another text | Now                  | This is awesome        |
|                      | add some             |                        |
|                      | multi line stuff     |                        |
+----------------------+----------------------+------------------------+

更多功能

use comfy_table::modifiers::UTF8_ROUND_CORNERS;
use comfy_table::presets::UTF8_FULL;
use comfy_table::*;

fn main() {
    let mut table = Table::new();
    table
        .load_preset(UTF8_FULL)
        .apply_modifier(UTF8_ROUND_CORNERS)
        .set_content_arrangement(ContentArrangement::Dynamic)
        .set_width(40)
        .set_header(vec!["Header1", "Header2", "Header3"])
        .add_row(vec![
            Cell::new("Center aligned").set_alignment(CellAlignment::Center),
            Cell::new("This is another text"),
            Cell::new("This is the third text"),
        ])
        .add_row(vec![
            "This is another text",
            "Now\nadd some\nmulti line stuff",
            "This is awesome",
        ]);

    // Set the default alignment for the third column to right
    let column = table.column_mut(2).expect("Our table has three columns");
    column.set_cell_alignment(CellAlignment::Right);

    println!("{table}");
}

创建一个具有UTF8样式的表格,并应用一个提供圆角效果的修改器。
此外,内容将根据给定的表格宽度动态换行。
如果未明确设置表格宽度,并且程序在终端中运行,则将使用终端大小。

除此之外,我们还设置了右列的默认对齐方式为 Right,以及左上单元格的对齐方式为 Center

╭────────────┬────────────┬────────────╮
│ Header1    ┆ Header2    ┆    Header3 │
╞════════════╪════════════╪════════════╡
│  This is a ┆ This is    ┆    This is │
│    text    ┆ another    ┆  the third │
│            ┆ text       ┆       text │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ This is    ┆ Now        ┆    This is │
│ another    ┆ add some   ┆    awesome │
│ text       ┆ multi line ┆            │
│            ┆ stuff      ┆            │
╰────────────┴────────────┴────────────╯

样式

use comfy_table::presets::UTF8_FULL;
use comfy_table::*;

fn main() {
    let mut table = Table::new();
    table.load_preset(UTF8_FULL)
        .set_content_arrangement(ContentArrangement::Dynamic)
        .set_width(80)
        .set_header(vec![
            Cell::new("Header1").add_attribute(Attribute::Bold),
            Cell::new("Header2").fg(Color::Green),
            Cell::new("Header3"),
        ])
        .add_row(vec![
             Cell::new("This is a bold text").add_attribute(Attribute::Bold),
             Cell::new("This is a green text").fg(Color::Green),
             Cell::new("This one has black background").bg(Color::Black),
        ])
        .add_row(vec![
            Cell::new("Blinky boi").add_attribute(Attribute::SlowBlink),
            Cell::new("This table's content is dynamically arranged. The table is exactly 80 characters wide.\nHere comes a reallylongwordthatshoulddynamicallywrap"),
            Cell::new("COMBINE ALL THE THINGS")
                .fg(Color::Green)
                .bg(Color::Black)
                .add_attributes(vec![
                    Attribute::Bold,
                    Attribute::SlowBlink,
                ])
        ]);

    println!("{table}");
}

此代码生成了文档顶部的表格。

代码示例

一些示例可以在 example 文件夹中找到。要测试一个示例,运行 cargo run --example $name. 例如。

cargo run --example readme_table

如果您需要更多信息,请查看 tests 文件夹。几乎每个功能都有测试,包括每个结果的表格的视觉预览。

功能标志

tty(已启用)

此标志启用了对终端的支持。具体来说,这意味着

  • 自动检测我们是否处于终端环境。仅在未提供显式的 Table::set_width 时使用。
  • 支持终端的 ANSI 转义代码样式。

custom_styling(已禁用)

此标志启用了对单元格内文本自定义样式的支持。

  • 即使您使用自己的 ANSI 转义序列,文本格式化仍然有效。
  • 彩虹文字
  • 使 comfy-table 变得慢 30-50%

reexport_crossterm(已禁用)

使用此标志,comfy-table 重新导出 crossterm 的 AttributeColor 枚举。默认情况下,导出的是镜像类型,内部映射到 crossterm 类型。

如果您在代码中同时使用 comfy-table 和 crossterm,并希望对所有内容使用 crossterm 的类型进行互操作,则此功能非常方便。

但是,如果您启用此功能,则表示您同意在次要/修补程序版本上进行破坏性更改。这意味着,每次您更新 comfy-table 时都必须更新 crossterm,并且您 不能 在 comfy-table 发布了包含该 crossterm 版本的新版本之前更新 crossterm。

贡献

Comfy-table 的主要重点是简洁和可靠。一组固定功能,适用于“常规”用例。

  • 常规表格(列、行、每列/行一个单元格)。
  • 根据给定宽度动态排列内容。
  • 在排列过程中进行某种手动干预。

如果您有想法或改进建议,适合项目的当前范围,请随时创建问题 :)!

然而,某些内容可能不太可能添加到项目中,因为它们极大地增加了库的复杂性或覆盖了非常具体的边缘情况。

此类功能包括

  • 嵌套表格
  • 跨越多个列/行的单元格
  • 从 CSV 转换到表格以及相反

不安全

Comfy-table 不允许在其代码库中使用 unsafe 代码。作为一个“简单”的格式化库,它也不需要在将来使用。

如果禁用了 tty 功能标志,这也适用于其所有依赖项。

然而,当启用 tty 时,Comfy-table 在其依赖项中使用两个不安全函数调用。
这两个调用可以通过显式调用 Table::force_no_tty 来禁用。

  1. crossterm::tty::IsTty。此函数用于检测我们是否目前处于 tty 上。仅在未通过 Table::set_width 提供显式宽度时调用。

    /// On unix the `isatty()` function returns true if a file
    /// descriptor is a terminal.
    #[cfg(unix)]
    impl<S: AsRawFd> IsTty for S {
        fn is_tty(&self) -> bool {
            let fd = self.as_raw_fd();
            unsafe { libc::isatty(fd) == 1 }
        }
    }
    
  2. crossterm::terminal::size。此函数用于检测我们处于 tty 上时的当前终端宽度。仅在未通过 Table::set_width 提供显式宽度时调用。

    http://rosettacode.org/wiki/Terminal_control/Dimensions#Library:_BSD_libc 这是一种用于通过文件描述符与 /dev/tty 通信的另一个 libc 调用。

    ...
    if wrap_with_result(unsafe { ioctl(fd, TIOCGWINSZ.into(), &mut size) }).is_ok() {
        Ok((size.ws_col, size.ws_row))
    } else {
        tput_size().ok_or_else(|| std::io::Error::last_os_error().into())
    }
    ...
    

与其他库的比较

以下为其他crate作者的官方声明。 此问题跟踪单 可用作入口,以找到其他项目中所有其他相关的 sibling 问题跟踪单。

Cli-table

cli-table 的主要重点是支持所有平台,同时限制依赖以保持编译时间和crate大小较低。

目前,此crate只引入了两个外部依赖(除 cli-table-derive 之外)

  • termcolor
  • unicode-width

启用 csv 功能后,它还会将 csv crate 作为依赖项引入。

Term-table

term-table 在功能方面相对基础。我的目标是为此项目提供一组良好的工具,用于渲染 CLI 表格,同时允许用户使用自己的工具(如颜色)。据我所知,term-table 的独特之处在于能够使表格的每一行有不同的列数。

Prettytables-rs

prettytables-rs 提供了格式化和对齐表格的功能。然而,它已被弃用,已请求在 rustsec/advisory-db 中添加条目。

Comfy-table

comfy-table 的一个主要重点是提供一个简约但可靠的库,用于构建基于文本的表格。这意味着代码经过了很好的测试,没有使用 unsafeunwrap,只有在我们可以绝对确定它是安全的情况下才会使用。在comfy-table的所有依赖项中,只有两次出现 unsafe,确切地说是位于 tty 通信代码中,该代码可以明确禁用。

另一个重点是动态长度内容排列。这意味着在构建一个算法以找到任何给定文本和终端宽度的(近)最佳表格布局方面投入了大量工作。

依赖项

~0.6–8.5MB
~61K SLoC