Smart adaptive formatting of tabular data.
This crate provides an idiomatic Rust library for building and printing tables with automatic column width calculation, tree rendering, multiple output formats, and a filter expression language.
Quick start
use ;
let mut table = new;
table.add_column;
table.add_column;
let l1 = table.new_line;
table.line_mut.set_data.set_data;
let l2 = table.new_line;
table.line_mut.set_data.set_data;
let output = print_table_to_string.unwrap;
assert!;
assert!;
Output modes
Set via [Table::set_output_mode]:
use ;
let mut table = new;
table.set_name;
table.new_column;
table.new_column;
let row = table.new_line;
table.line_mut.set_data.set_data;
// JSON output
table.set_output_mode;
let json = print_table_to_string.unwrap;
assert!;
// Export (shell-friendly KEY="value" pairs)
table.set_output_mode;
let export = print_table_to_string.unwrap;
assert!;
| Mode | Description |
|---|---|
[OutputMode::Normal] |
Human-readable with column alignment and padding |
[OutputMode::Raw] |
Compact, separator-delimited (no padding) |
[OutputMode::Export] |
NAME="value" pairs for shell consumption |
[OutputMode::Json] |
JSON array of objects |
[OutputMode::ShellVar] |
Like Export but with shell-safe column names |
Column width hints
Width hints guide the print engine's layout algorithm. Set them via the
builder methods on [Column]:
| Method | Effect |
|---|---|
| (default) | Auto — sized to fit content |
[Column::width_fixed] |
Absolute minimum character width |
[Column::width_fraction] |
Fraction of terminal width (only when output is a terminal) |
[Column::width] |
Set a [WidthHint] enum value directly |
Column flags
Per-column rendering behavior is controlled via builder methods on [Column]:
| Method | Effect |
|---|---|
[Column::tree] |
Draws tree connectors (use with [Table::new_line] parent) |
[Column::right] |
Right-aligns cell data |
[Column::trunc] |
Truncates data that exceeds the column width |
[Column::wrap] |
Wraps long data across multiple output lines |
[Column::hidden] |
Stores data in memory but omits it from output |
[Column::strict_width] |
Never shrink the column below its hint width |
[Column::no_extremes] |
Ignore outlier values when calculating widths |
Tree rendering
Mark a column as a tree column with [Column::tree] and pass a parent
[LineId] when creating child lines. The print engine draws Unicode (or
ASCII) tree connectors automatically.
use ;
let mut table = new;
table.enable_no_headings;
table.enable_ascii;
table.add_column;
let root = table.new_line;
table.line_mut.set_data;
let child1 = table.new_line;
table.line_mut.set_data;
let child2 = table.new_line;
table.line_mut.set_data;
let output = print_table_to_string.unwrap;
assert!;
assert!;
Sorting
Sort child lines under a parent using [Table::sort]. A custom comparator
can be set per-column with [Column::cmp_func]. Sorting reorders
children within each parent node; for flat tables, add rows as children of
a single root line.
use ;
let mut table = new;
table.enable_ascii;
table.enable_no_headings;
table.add_column;
let root = table.new_line;
table.line_mut.set_data;
for name in
table.sort; // sort children of root by column 0
let output = print_table_to_string.unwrap;
let lines: = output.lines.collect;
// lines[0] = root, children appear sorted after it
assert!;
assert!;
assert!;
Groups
Groups express M:N relationships between lines — multiple lines can be "members" of a group, and other lines can be "children" of that group. The print engine draws bracket connectors on the left margin.
use ;
let mut table = new;
table.enable_no_headings;
table.enable_ascii;
table.set_termwidth;
table.set_termforce;
table.new_column;
let group = table.new_group;
let m1 = table.new_line;
table.line_mut.set_data;
let m2 = table.new_line;
table.line_mut.set_data;
let child = table.new_line;
table.line_mut.set_data;
table.group_add_member;
table.group_add_member;
table.group_add_child;
let output = print_table_to_string.unwrap;
assert!;
assert!;
assert!;
Cloning
Both [Table] and [Column] implement [Clone]. Cloning a table produces
an independent copy including all lines and column definitions. If a column
has a custom comparator set via [Column::cmp_func], the clone shares
the same comparator function (via Arc).
use Table;
let mut table = new;
table.new_column;
let row = table.new_line;
table.line_mut.set_data;
let clone = table.clone;
assert_eq!;
Filtering
Parse filter expressions with [Filter::parse] and evaluate them against
line data. Supports comparisons, boolean logic, regex matching, and
integer suffixes (K, M, G, ...).
use Filter;
let f = parse.unwrap;
let matches = f.evaluate.unwrap;
assert!;