Streaming
The standard print_table API requires building the entire table in memory
before printing. For large or unbounded datasets, the streaming writer lets
you output rows immediately as data arrives.
Basic usage
Configure columns on a Table as usual, then create a streaming writer.
The writer prints the header (if enabled) and any opening syntax
automatically. Build rows with begin_row, populate them with set, then call finish
to flush each row. Call close when done.
use cols::{Table, Column};
fn main() {
let mut table = Table::new();
table.add_column(Column::new("NAME").width_fixed(10));
table.add_column(Column::new("SIZE").width_fixed(6).right(true));
let stdout = std::io::stdout();
let mut out = stdout.lock();
let mut w = table.streaming_writer(&mut out).unwrap();
w.begin_row(None).set("NAME", "sda").set("SIZE", "100G").finish().unwrap();
w.begin_row(None).set("NAME", "sdb").set("SIZE", "50G").last(true).finish().unwrap();
w.close().unwrap();
}
Setting cell data
Use set() to populate cells. It accepts both column names and indices
via the ColumnKey trait:
row.set("NAME", "sda"); // by column name
row.set(0, "sda"); // by column index
Both can be mixed freely on the same row.
Output modes
The streaming writer supports all output modes. Set the mode on the table before creating the writer:
table.output_mode_set(OutputMode::Json);
table.name_set("devices");
let mut w = table.streaming_writer(&mut out).unwrap();
For Normal and Markdown modes, columns should have fixed width hints
(width_fixed) since the writer can’t scan all data upfront to calculate
widths.
Tree streaming
Pass a parent RowId to begin_row to build tree hierarchies
incrementally. Call .last(true) on the row builder to mark a row as the
last child of its parent – this controls whether a └─ (last) or ├─
(more siblings) connector is drawn.
use cols::{Table, Column};
fn main() {
let mut table = Table::new();
table.headings_set(false);
table.add_column(Column::new("NAME").width_fixed(20).tree(true));
table.add_column(Column::new("SIZE").width_fixed(8).right(true));
let stdout = std::io::stdout();
let mut out = stdout.lock();
let mut w = table.streaming_writer(&mut out).unwrap();
let root = w.begin_row(None)
.set("NAME", "sda").set("SIZE", "500G")
.last(true)
.finish().unwrap();
w.begin_row(Some(root))
.set("NAME", "sda1").set("SIZE", "256M")
.finish().unwrap();
w.begin_row(Some(root))
.set("NAME", "sda2").set("SIZE", "250G")
.last(true)
.finish().unwrap();
w.close().unwrap();
}
Output:
sda 500G
├─sda1 256M
└─sda2 250G
This is particularly useful for recursive directory walkers, process trees, or any case where the data is discovered incrementally.
Limitations
- Sorting is not supported in streaming mode (it requires all data).
- Group rendering is not supported.
- Auto-sized columns (no width hint) work for Raw, CSV, Export, ShellVar, and JSON modes, but Normal and Markdown modes need fixed widths since the writer can’t pre-scan the data.