Cookbook
Complete examples showing cols in real-world scenarios. See also the examples/ directory in the repository.
lsblk-like output
A realistic example with trees, fractional widths, and multiple output modes:
use cols::{Table, Column, TermForce, print_table};
fn main() {
let mut t = Table::new();
t.name_set("blockdevices");
t.termwidth_set(80);
t.termforce_set(TermForce::Always);
t.add_column(
Column::new("NAME")
.width_fraction(0.25)
.tree(true)
.no_extremes(true),
);
t.add_column(Column::new("MAJ:MIN").width_fixed(6));
t.add_column(Column::new("RM").width_fixed(1).right(true));
t.add_column(Column::new("SIZE").width_fixed(5).right(true));
t.add_column(Column::new("RO").width_fixed(1).right(true));
t.add_column(Column::new("TYPE").width_fixed(4));
t.add_column(Column::new("MOUNTPOINTS").width_fraction(0.1).wrap(true));
let sda = t.new_line(None);
t.line_mut(sda)
.data_set(0, "sda")
.data_set(1, "8:0")
.data_set(2, "1")
.data_set(3, "0B")
.data_set(4, "0")
.data_set(5, "disk");
let nvme = t.new_line(None);
t.line_mut(nvme)
.data_set(0, "nvme0n1")
.data_set(1, "259:0")
.data_set(2, "0")
.data_set(3, "931.5G")
.data_set(4, "0")
.data_set(5, "disk");
let p1 = t.new_line(Some(nvme));
t.line_mut(p1)
.data_set(0, "nvme0n1p1")
.data_set(1, "259:1")
.data_set(2, "0")
.data_set(3, "600M")
.data_set(4, "0")
.data_set(5, "part")
.data_set(6, "/boot/efi");
let p2 = t.new_line(Some(nvme));
t.line_mut(p2)
.data_set(0, "nvme0n1p2")
.data_set(1, "259:2")
.data_set(2, "0")
.data_set(3, "2G")
.data_set(4, "0")
.data_set(5, "part")
.data_set(6, "/boot");
let p3 = t.new_line(Some(nvme));
t.line_mut(p3)
.data_set(0, "nvme0n1p3")
.data_set(1, "259:3")
.data_set(2, "0")
.data_set(3, "928.9G")
.data_set(4, "0")
.data_set(5, "part");
let luks = t.new_line(Some(p3));
t.line_mut(luks)
.data_set(0, "luks-62d09206-d2b0-48d8-9164-a8487c42e31b")
.data_set(1, "252:0")
.data_set(2, "0")
.data_set(3, "928.9G")
.data_set(4, "0")
.data_set(5, "crypt")
.data_set(6, "/home");
print_table(&t, &mut std::io::stdout().lock()).unwrap();
}
Normal output:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 1 0B 0 disk
nvme0n1 259:0 0 931.5G 0 disk
├─nvme0n1p1 259:1 0 600M 0 part /boot/efi
├─nvme0n1p2 259:2 0 2G 0 part /boot
└─nvme0n1p3 259:3 0 928.9G 0 part
└─luks-62d09206-d2b0-48d8-9164-a8487c42e31b 252:0 0 928.9G 0 crypt /home
Group members only
use cols::{Table, Column, TermForce, print_table};
fn main() {
let mut t = Table::new();
t.termwidth_set(40);
t.termforce_set(TermForce::Always);
t.headings_set(false);
t.new_column("NAME");
t.add_column(Column::new("SIZE").right(true));
let g = t.new_group();
let l1 = t.new_line(None);
t.line_mut(l1).data_set(0, "alpha").data_set(1, "10");
let l2 = t.new_line(None);
t.line_mut(l2).data_set(0, "beta").data_set(1, "20");
let l3 = t.new_line(None);
t.line_mut(l3).data_set(0, "gamma").data_set(1, "30");
t.group_add_member(g, l1);
t.group_add_member(g, l2);
t.group_add_member(g, l3);
print_table(&t, &mut std::io::stdout().lock()).unwrap();
}
Output:
┌─alpha 10
├─beta 20
└─gamma 30
Filtering lines before display
use cols::{Table, Filter, print_table_to_string};
fn main() {
let mut table = Table::new();
table.new_column("NAME");
table.new_column("SIZE");
let data = vec![("sda", "1073741824"), ("sdb", "536870912"), ("sr0", "0")];
for (name, size) in &data {
let row = table.new_line(None);
table.line_mut(row).data_set(0, name).data_set(1, size);
}
let filter = Filter::parse("SIZE > 512M").unwrap();
let mut filtered = Table::new();
filtered.new_column("NAME");
filtered.new_column("SIZE");
for id in table.line_ids() {
let line = table.line(id);
let matches = filter.evaluate(|col| match col {
"NAME" => line.data_get(0).map(String::from),
"SIZE" => line.data_get(1).map(String::from),
_ => None,
}).unwrap();
if matches {
let row = filtered.new_line(None);
filtered.line_mut(row)
.data_set(0, line.data_get(0).unwrap_or(""))
.data_set(1, line.data_get(1).unwrap_or(""));
}
}
let output = print_table_to_string(&filtered).unwrap();
assert!(output.contains("sda"));
assert!(!output.contains("sr0"));
}