tablestream

A streaming table formatter for the console

4 releases

0.1.3 Aug 6, 2021
0.1.2 Aug 6, 2021
0.1.1 Aug 5, 2021
0.1.0 Aug 5, 2021

#473 in Visualization

MIT/Apache

33KB
684 lines

TableStream

Stream data to the terminal and display it in ASCII tables.

TableStream will initially buffer some rows and use them to automatically determine appropriate widths for columns. It will try to automatically detect the current terminal's width and fit the rows into that width.

After that, it clears the buffer and just streams data directly to your output. (An io::Write)

See the API Docs for code examples. Install from crates.io.

Exmaple GIF

Current Limitations

  • Doesn't handle right-to-left text. (Have tips on doing this in a terminal!?)
  • Emoji aren't handled.
  • Bengali seems to not render properly in Widnows terminal, so that's not supported. (Though maybe it'll work for you elsewhere?)

Future Features?

  • Could add options for colors.

lib.rs:

TableStream is a tool for streaming tables out to the terminal. It will buffer some number of rows before first output and try to automatically determine appropriate widths for each column.

// Some sample data we want to show:
struct City {
    name: String,
    country: String,
    population: u32,
}

impl City {
    fn new(name: &str, country: &str, population: u32) -> Self {
        Self { name: name.to_string(), country: country.to_string(), population, }
    }
}

fn largest_cities() -> Vec<City> {
   vec![
       City::new("Shanghai", "China", 24_150_000),
       City::new("Beijing", "China", 21_700_000),
       City::new("Lagos", "Nigeria", 21_320_000),
   ]
}

let mut out = io::stdout();
let mut stream = Stream::new(&mut out, vec![
    // There are three different ways to specify which data to show in each column.
    // 1. A closure that takes a formatter, and a reference to your type, and writes it out.
    Column::new(|f, c: &City| write!(f, "{}", &c.name)).header("City"),
     
    // 2. Or we can use a shortcut macro to just show a single field:
    // (It must implement fmt::Display)
    col!(City: .country).header("Country"),

    // 3. You can optionally specify a formatter:
    // (Note: don't use padding/alignment in your formatters. TableStream will do that for you.)
    col!(City: "{:.2e}", .population).header("Population"),
]);

// Stream our data:
for city in largest_cities() {
   stream.row(city)?;
}

stream.finish()?;
 

Dependencies

~3.5MB
~55K SLoC