Skip to content

Latest commit

 

History

14 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rustom

A Rust library for building rich, stateful terminal user interfaces and dashboards.

rustom follows the immediate mode widget architecture common to modern Rust TUI libraries: widgets are cheap, disposable values that consume themselves when rendered into an in memory Buffer, the Terminal diffs the current buffer against the previous frame, and only the cells that actually changed get written to the real terminal. Rendering is backend agnostic through a Backend trait, with a crossterm implementation included.

Features

  • Buffer / Cell: the in memory grid every widget renders into.
  • Layout: split a screen area into rows or columns using Length, Percentage, Ratio, Min, Max, and Fill constraints.
  • Style, Color, Modifier: foreground and background colors plus text attributes like bold, italic, and underline.
  • Span, Line, Text: composable styled text.
  • Widgets: Block, Paragraph (with word wrap and scrolling), List (with selection and auto scroll), Table (with a header row and per column widths), Gauge, LineGauge, Tabs, Sparkline, BarChart, and Scrollbar.
  • Terminal: double buffered, diff based rendering with a crossterm backend and init / restore helpers for raw mode and the alternate screen.

Installation

[dependencies]
rustom = "0.1.0"

Quick start

use std::io;
use rustom::layout::{Constraint, Direction, Layout};
use rustom::style::{Color, Style};
use rustom::widgets::{Block, Paragraph};

fn run() -> io::Result<()> {
    let mut terminal = rustom::init()?;

    terminal.draw(|frame| {
        let chunks = Layout::default()
            .direction(Direction::Vertical)
            .constraints([Constraint::Length(3), Constraint::Fill(1)])
            .split(frame.area());

        frame.render_widget(Block::bordered().title("rustom"), chunks[0]);

        let body = Paragraph::new("Hello from rustom.")
            .style(Style::new().fg(Color::Cyan))
            .block(Block::bordered());
        frame.render_widget(body, chunks[1]);
    })?;

    rustom::restore()?;
    Ok(())
}

Run the full demo, which wires up tabs, a list with a scrollbar, a table, a paragraph, a sparkline, a bar chart, a gauge, and a line gauge in a single event loop:

cargo run --example demo

Press q to quit, j / k or the arrow keys to move the list selection, and Tab to switch tabs.

Design notes

  • Widgets implement Widget::render(self, area, buf), consuming themselves. Build a fresh widget from your application state every frame rather than mutating one in place.
  • Widgets that need to remember something across frames (a selected list index, a scroll offset) implement StatefulWidget instead, and take a &mut State that you own and store alongside the rest of your application state.
  • Layout::split uses a two pass greedy solver: fixed size constraints (Length, Percentage, Ratio, Max) claim their space first, then leftover space is divided among Min and Fill segments in proportion to their weights.
  • Chart (axes and line/scatter datasets) and Canvas (arbitrary line drawing) are not implemented yet. Everything else in the widget list above is.

License

Licensed under either of

at your option.

About

A fast, keyboard first terminal UI built with Rust.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages