Rust表格生成库cli-table-derive的使用,通过派生宏快速创建格式化的命令行表格输出

Rust表格生成库cli-table-derive的使用,通过派生宏快速创建格式化的命令行表格输出

Rust crate用于在命令行上打印表格。

使用方法

在您的Cargo.tomldependencies部分添加cli-table

[dependencies]
cli-table = "0.5"

简单用法

use cli_table::{format::Justify, print_stdout, Cell, Style, Table};

// 创建表格数据
let table = vec![
    vec!["Tom".cell(), 10.cell().justify(Justify::Right)],
    vec!["Jerry".cell(), 15.cell().justify(Justify::Right)],
    vec!["Scooby Doo".cell(), 20.cell().justify(Justify::Right)],
]
.table()
.title(vec![
    "Name".cell().bold(true),
    "Age (in years)".cell().bold(true),
])
.bold(true);

// 打印表格到标准输出
assert!(print_stdout(table).is_ok());

下面是我们刚刚创建的表格的输出:

+------------+----------------+
| Name       | Age (in years) |  <-- 这一行和所有边框/分隔符
+------------+----------------+      将以粗体显示
| Tom        |             10 |
+------------+----------------+
| Jerry      |             15 |
+------------+----------------+
| Scooby Doo |             25 |
+------------+----------------+

Display trait 实现

要获取TableStructDisplay trait实现,请在结构体上使用display()函数来获取实现Display trait的TableDisplay实例。

use cli_table::{format::Justify, Cell, Style, Table};

// 创建表格数据
let table = vec![
    vec!["Tom".cell(), 10.cell().justify(Justify::Right)],
    vec!["Jerry".cell(), 15.cell().justify(Justify::Right)],
    vec!["Scooby Doo".cell(), 20.cell().justify(Justify::Right)],
]
.table()
.title(vec![
    "Name".cell().bold(true),
    "Age (in years)".cell().bold(true),
])
.bold(true);

// 获取Display实现
let table_display = table.display().unwrap();

// 使用println!打印表格
println!("{}", table_display);

下面是我们刚刚创建的表格的输出:

+------------+----------------+
| Name       | Age (in years) |  <-- 这一行和所有边框/分隔符
+------------+----------------+      将以粗体显示
| Tom        |             10 |
+------------+----------------+
| Jerry      |             15 |
+------------+----------------+
| Scooby Doo |             25 |
+------------+----------------+

派生宏

#[derive(Table)]也可以用于将结构体的Vec或切片打印为表格。

use cli_table::{format::Justify, print_stdout, Table, WithTitle};

// 使用派生宏定义User结构体
#[derive(Table)]
struct User {
    #[table(title = "ID", justify = "Justify::Right")]
    id: u64,
    #[table(title = "First Name")]
    first_name: &'static str,
    #[table(title = "Last Name")]
    last_name: &'static str,
}

// 创建用户数据
let users = vec![
    User {
        id: 1,
        first_name: "Scooby",
        last_name: "Doo",
    },
    User {
        id: 2,
        first_name: "John",
        last_name: "Cena",
    },
];

// 打印带标题的表格
assert!(print_stdout(users.with_title()).is_ok());

下面是我们使用派生宏创建的表格的输出:

+----+------------+-----------+
| ID | First Name | Last Name |  <-- 这一行将以粗体显示
+----+------------+-----------+
|  1 | Scooby     | Doo       |
+----+------------+-----------+
|  2 | John       | Cena      |
+----+------------+-----------+

字段属性

  • title | name: 用于指定列的标题。用法:#[table(title = "Title")]
  • justify: 用于水平对齐列的内容。用法:#[table(justify = "Justify::Right")]
  • align: 用于垂直对齐列的内容。用法:#[table(align = "Align::Top")]
  • color: 用于指定列内容的颜色。用法:#[table(color = "Color::Red")]
  • bold: 用于指定列内容的粗体。用法:#[table(bold)]
  • order: 用于在打印时对表格中的列进行排序。用法:#[table(order = <usize>)]。列将根据它们的顺序进行排序。例如,order = 0的列将显示在左侧,然后是order = 1的列,依此类推。
  • display_fn: 用于打印未实现Display trait的类型。用法:#[table(display_fn = "<func_name>")]。提供的函数签名应为fn <func_name>(value: &<type>) -> impl Display
  • customize_fn: 用于自定义单元格的样式。用法:#[table(customize_fn = "<func_name>")]。提供的函数签名应为fn <func_name>(cell: CellStruct, value: &<type>) -> CellStruct。当您希望根据单元格的内容更改其格式/样式时,可以使用此属性。请注意,这将覆盖其他属性完成的所有样式设置。
  • skip: 用于从表格中跳过字段。用法:#[table(skip)]

CSV

此crate还与csv crate集成。启用"csv"功能后,您可以使用TryFrom<&mut Reader> for TableStruct trait实现将csv::Reader转换为TableStruct

样式

表格/单元格的样式可以通过调用[Style] trait的函数来修改。它由[TableStruct]和[CellStruct]实现。

对于单独格式化表格的每个单元格,可以使用CellStruct中的justifyalignpadding函数。

除此之外,表格的边框和分隔符可以通过在TableStruct中调用borderseparator函数来自定义。例如,创建一个无边框表格:

use cli_table::{Cell, Table, TableStruct, format::{Justify, Border}, print_stdout};

// 获取表格数据的函数
fn get_table() -> TableStruct {
    vec![
        vec!["Tom".cell(), 10.cell().justify(Justify::Right)],
        vec!["Jerry".cell(), 15.cell().justify(Justify::Right)],
        vec!["Scooby Doo".cell(), 20.cell().justify(Justify::Right)],
    ]
    .table()
}

// 创建无边框表格
let table = get_table().border(Border::builder().build()); // 为表格附加空边框
assert!(print_stdout(table).is_ok());

功能

  • derive: 启用派生宏以使用结构体创建表格。默认启用。
  • csv: 启用使用csv打印表格的支持。默认启用。

完整示例代码

use cli_table::{format::Justify, print_stdout, Table, WithTitle};

// 使用派生宏定义User结构体
#[derive(Table)]
struct User {
    #[table(title = "ID", justify = "Justify::Right")]
    id: u64,
    #[table(title = "First Name")]
    first_name: &'static str,
    #[table(title = "Last Name")]
    last_name: &'static str,
}

fn main() {
    // 创建用户数据
    let users = vec![
        User {
            id: 1,
            first_name: "Scooby",
            last_name: "Doo",
        },
        User {
            id: 2,
            first_name: "John",
            last_name: "Cena",
        },
    ];

    // 打印带标题的表格
    assert!(print_stdout(users.with_title()).is_ok());
}

1 回复

Rust表格生成库cli-table-derive使用指南

概述

cli-table-derive是一个基于派生宏的Rust库,用于快速创建格式化的命令行表格输出。它通过自定义派生宏简化了表格的创建过程,让开发者能够专注于数据结构而不是格式化细节。

安装方法

在Cargo.toml中添加依赖:

[dependencies]
cli-table = "0.4"
cli-table-derive = "0.4"

基本使用方法

1. 定义数据结构

use cli_table::{Table, format::Justify};
use cli_table_derive::Table;

#[derive(Table)]
struct User {
    #[table(title = "ID", justify = "Justify::Right")]
    id: u64,
    
    #[table(title = "Name")]
    name: String,
    
    #[table(title = "Email")]
    email: String,
    
    #[table(title = "Active", justify = "Justify::Center")]
    active: bool,
}

2. 创建表格数据

let users = vec![
    User {
        id: 1,
        name: "Alice".to_string(),
        email: "alice@example.com".to_string(),
        active: true,
    },
    User {
        id: 2,
        name: "Bob".to_string(),
        email: "bob@example.com".to_string(),
        active: false,
    },
];

3. 输出表格

use cli_table::{print_stdout, Table};

let table = users.table()
    .title(vec![
        "ID".cell().bold(true),
        "Name".cell().bold(true),
        "Email".cell().bold(true),
        "Active".cell().bold(true),
    ]);

print_stdout(table).unwrap();

高级功能示例

自定义格式化

#[derive(Table)]
struct Product {
    #[table(title = "Product ID")]
    id: u64,
    
    #[table(title = "Name")]
    name: String,
    
    #[table(title = "Price", justify = "Justify::Right")]
    #[table(format_fn = "format_price")]
    price: f64,
}

fn format_price(price: &f64) -> String {
    format!("${:.2}", price)
}

嵌套表格结构

#[derive(Table)]
struct Order {
    #[table(title = "Order ID")]
    id: u64,
    
    #[table(title = "Customer")]
    customer: String,
    
    #[table(title = "Products")]
    #[table(display_fn = "display_products")]
    products: Vec<Product>,
}

fn display_products(products: &Vec<Product>) -> String {
    products.iter()
        .map(|p| p.name.clone())
        .collect::<Vec<_>>()
        .join(", ")
}

输出样式配置

use cli_table::{Table, format::{Border, Style}};

let style = Style::default()
    .border(Border::builder().build())
    .title(vec![
        "ID".cell().bold(true),
        "Name".cell().foreground_color(Some(cli_table::Color::Green)),
    ]);

let table = users.table().style(style);
print_stdout(table).unwrap();

完整示例

use cli_table::{print_stdout, Table};
use cli_table_derive::Table;

#[derive(Table)]
struct Book {
    #[table(title = "ISBN")]
    isbn: String,
    
    #[table(title = "Title")]
    title: String,
    
    #[table(title = "Author")]
    author: String,
    
    #[table(title = "Price", justify = "Justify::Right")]
    price: f64,
}

fn main() {
    let books = vec![
        Book {
            isbn: "978-0134093413".to_string(),
            title: "The Rust Programming Language".to_string(),
            author: "Steve Klabnik, Carol Nichols".to_string(),
            price: 39.99,
        },
        Book {
            isbn: "978-1718500440".to_string(),
            title: "Black Hat Rust".to_string(),
            author: "Sylvain Kerkour".to_string(),
            price: 49.99,
        },
    ];

    let table = books.table();
    print_stdout(table).unwrap();
}

这个库提供了简单直观的方式来创建美观的命令行表格,特别适合需要展示结构化数据的CLI应用程序。

回到顶部