MCPcopy Index your code
hub / github.com/Dicklesworthstone/rich_rust

github.com/Dicklesworthstone/rich_rust @v0.2.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.2.1 ↗ · + Follow
4,489 symbols 22,412 edges 135 files 400 documented · 9%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

rich_rust

rich_rust - Beautiful terminal output for Rust

CI codecov Crates.io Documentation License: MIT

Beautiful terminal output for Rust, inspired by Python's Rich.

Quick Install

cargo add rich_rust

Or with all features: cargo add rich_rust --features full


Run the Demo

See rich_rust in action with the Nebula Deploy demo — a complete showcase of terminal UI capabilities wrapped in a fictional deployment narrative.

# Full demo with all features (recommended)
cargo run --bin demo_showcase --features showcase

# Quick mode for faster run
cargo run --bin demo_showcase --features showcase -- --quick

# CI-safe mode (non-blocking, deterministic output)
cargo run --bin demo_showcase --features showcase -- --quick --no-live --no-interactive

# List available scenes
cargo run --bin demo_showcase --features showcase -- --list-scenes

# Run a specific scene
cargo run --bin demo_showcase --features showcase -- --scene hero

What the demo showcases: - Typography — styled text, colors, bold/italic/underline, themes - Tables — alignment, borders, headers, badges, ASCII fallback - Panels — box styles, titles, padding, nested layouts - Trees — hierarchical data, custom guides, icons - Progress — bars, spinners, live updates - Syntax — code highlighting for 100+ languages (Rust, YAML, TOML, etc.) - Markdown — CommonMark + GFM rendering - JSON — pretty-printed, theme-aware output - Tracing — structured logging integration - Export — HTML/SVG capture of terminal output


TL;DR

The Problem

Building beautiful terminal UIs in Rust is tedious. You either: - Write raw ANSI escape codes (error-prone, unreadable) - Use low-level crates that require boilerplate for simple things - Miss features like automatic terminal capability detection, tables, progress bars

The Solution

rich_rust brings Python Rich's ergonomic API to Rust: styled text, tables, panels, progress bars, syntax highlighting, and more. Zero unsafe code, automatic terminal detection.

Why Use rich_rust?

Feature rich_rust Raw ANSI colored termion
Markup syntax ([bold red]text[/]) Yes No No No
Tables with auto-sizing Yes No No No
Panels and boxes Yes No No No
Progress bars & spinners Yes No No No
Syntax highlighting Yes No No No
Markdown rendering Yes No No No
Auto color downgrade Yes No Partial No
Unicode width handling Yes No No Partial

Quick Example

use rich_rust::prelude::*;

fn main() {
    let console = Console::new();

    // Styled text with markup
    console.print("[bold green]Success![/] Operation completed.");
    console.print("[red on white]Error:[/] [italic]File not found[/]");

    // Horizontal rule
    console.rule(Some("Configuration"));

    // Tables
    let mut table = Table::new()
        .title("Users")
        .with_column(Column::new("Name"))
        .with_column(Column::new("Role").justify(JustifyMethod::Right));

    table.add_row_cells(["Alice", "Admin"]);
    table.add_row_cells(["Bob", "User"]);

    console.print_renderable(&table);

    // Panels
    let panel = Panel::from_text("Hello, World!")
        .title("Greeting")
        .width(40);

    console.print_renderable(&panel);
}

Output:

Success! Operation completed.
Error: File not found
─────────────────── Configuration ───────────────────
┌─────────────────────── Users ───────────────────────┐
│ Name   │   Role │
├────────┼────────┤
│ Alice  │  Admin │
│ Bob    │   User │
└────────────────────────────────────────────────────┘
┌─────────── Greeting ───────────┐
│ Hello, World!                  │
└────────────────────────────────┘

Design Philosophy

1. Zero Unsafe Code

#![forbid(unsafe_code)]

The entire codebase uses safe Rust. No segfaults, no data races, no undefined behavior.

2. Python Rich Compatibility

API and behavior closely follow Python Rich. If you know Rich, you know rich_rust. The RICH_SPEC.md documents every behavioral detail.

3. Renderable Extensibility

Instead of Python's duck typing, rich_rust uses explicit render methods and an optional measurement trait:

use rich_rust::console::{Console, ConsoleOptions};
use rich_rust::measure::{Measurement, RichMeasure};
use rich_rust::segment::Segment;

struct MyRenderable;

impl MyRenderable {
    fn render(&self, width: usize) -> Vec<Segment> {
        vec![Segment::plain(format!("width={width}"))]
    }
}

impl RichMeasure for MyRenderable {
    fn rich_measure(&self, _console: &Console, _options: &ConsoleOptions) -> Measurement {
        Measurement::exact(10)
    }
}

Renderables expose render(...) -> Vec<Segment>. Implement RichMeasure to participate in layout width calculations.

4. Automatic Terminal Detection

rich_rust detects terminal capabilities at runtime: - Color support (4-bit, 8-bit, 24-bit truecolor) - Terminal dimensions - Unicode support - Legacy Windows console

Colors automatically downgrade to what the terminal supports.

5. Minimal Dependencies

Core functionality has few dependencies. Optional features (syntax highlighting, markdown, JSON, tracing) are behind feature flags to keep compile times fast.


Comparison vs Alternatives

Feature rich_rust Python Rich colored termcolor owo-colors
Language Rust Python Rust Rust Rust
Markup parsing [bold]text[/] [bold]text[/] No No No
Tables Yes Yes No No No
Panels/Boxes Yes Yes No No No
Progress bars Yes Yes No No No
Trees Yes Yes No No No
Syntax highlighting Yes (syntect) Yes (Pygments) No No No
Markdown Yes Yes Yes No No
JSON pretty-print Yes Yes No No No
Color downgrade Auto Auto Partial Yes No
Zero unsafe Yes N/A Yes Yes Yes
No runtime Yes No (Python) Yes Yes Yes
Single binary Yes No Yes Yes Yes

When to use rich_rust: - You want Python Rich's features in Rust - You need tables, panels, or progress bars - You want markup syntax for styling - You're building CLI tools that need beautiful output

When to use alternatives: - colored: Simple color-only needs, minimal dependencies - termcolor: Cross-platform color with Windows support - owo-colors: Zero-allocation, const colors - Python Rich: You're writing Python


Installation

From crates.io

cargo add rich_rust

With Optional Features

# Syntax highlighting
cargo add rich_rust --features syntax

# Markdown rendering
cargo add rich_rust --features markdown

# JSON pretty-printing
cargo add rich_rust --features json

# Tracing integration
cargo add rich_rust --features tracing

# All features
cargo add rich_rust --features full

From Source

git clone https://github.com/Dicklesworthstone/rich_rust
cd rich_rust
cargo build --release

Cargo.toml

[dependencies]
rich_rust = "0.1"

# Or with features:
rich_rust = { version = "0.1", features = ["full"] }

Quick Start

1. Create a Console

use rich_rust::prelude::*;

let console = Console::new();

2. Print Styled Text

// Using markup syntax
console.print("[bold]Bold[/] and [italic red]italic red[/]");

// Using explicit style
console.print_styled("Styled text", Style::new().bold().underline());

// Plain text (no markup parsing)
console.print_plain("[brackets] are literal here");

3. Create a Table

let mut table = Table::new()
    .title("Data")
    .with_column(Column::new("Key"))
    .with_column(Column::new("Value").justify(JustifyMethod::Right));

table.add_row_cells(["version", "1.0.0"]);
table.add_row_cells(["status", "active"]);

console.print_renderable(&table);

4. Create a Panel

let panel = Panel::from_text("Important message here")
    .title("Notice")
    .subtitle("v1.0")
    .width(50);

console.print_renderable(&panel);

5. Print a Rule

// Simple rule
console.rule(None);

// Rule with title
console.rule(Some("Section"));

// Styled rule
let rule = Rule::with_title("Custom")
    .style(Style::parse("cyan bold").unwrap_or_default())
    .align_left();
console.print_renderable(&rule);

Feature Reference

Markup Syntax

Markup Effect
[bold]text[/] Bold text
[italic]text[/] Italic text
[underline]text[/] Underlined text
[red]text[/] Red foreground
[on blue]text[/] Blue background
[bold red on white]text[/] Combined styles
[#ff0000]text[/] Hex color
[rgb(255,0,0)]text[/] RGB color
[color(196)]text[/] 256-color palette

Themes (Named Styles)

Python Rich defines many named styles (e.g. rule.line, table.header). rich_rust ports this theme system and lets you add custom names:

use rich_rust::prelude::*;

let theme = Theme::from_style_definitions([("warning", "bold red")], true).unwrap();
let console = Console::builder().theme(theme).build();
console.print("[warning]Danger[/]");

Style Attributes

Style::new()
    .bold()
    .italic()
    .underline()
    .strikethrough()
    .dim()
    .reverse()
    .foreground(Color::parse("red").unwrap())
    .background(Color::parse("white").unwrap())

Color Systems

System Colors Detection
Standard 16 Basic terminals
256-color 256 Most modern terminals
Truecolor 16M iTerm2, Windows Terminal, etc.

Box Styles

Panel::from_text("content").rounded()  // ╭─╮ (default)
Panel::from_text("content").square()   // ┌─┐
Panel::from_text("content").heavy()    // ┏━┓
Panel::from_text("content").double()   // ╔═╗
Panel::from_text("content").ascii()    // +-+

Progress Bars

let bar = ProgressBar::new()
    .completed(75)
    .total(100)
    .width(40);

console.print_renderable(&bar);

Trees

let mut root = TreeNode::new("Root");
root.add_child(TreeNode::new("Child 1"));
root.add_child(TreeNode::new("Child 2"));

let tree = Tree::new(root);
console.print_renderable(&tree);

Live Updates

use rich_rust::prelude::*;

fn main() -> std::io::Result<()> {
    let console = Console::new().shared();
    let live = Live::new(console.clone()).renderable(Text::new("Loading..."));

    live.start(true)?;
    live.update(Text::new("Done!"), true);
    live.stop()?;

    Ok(())
}

For external writers, use live.stdout_proxy() / live.stderr_proxy() to route output through the Live display.

Layouts

use rich_rust::prelude::*;

let mut layout = Layout::new().name("root");
layout.split_column(vec![
    Layout::new()
        .name("header")
        .size(3)
        .renderable(Panel::from_text("Header")),
    Layout::new().name("body").ratio(1),
]);

if let Some(body) = layout.get_mut("body") {
    body.split_row(vec![
        Layout::new().name("left").ratio(1).renderable(Panel::from_text("Left")),
        Layout::new().name("right").ratio(2).renderable(Panel::from_text("Right")),
    ]);
}

console.print_renderable(&layout);

Logging

use rich_rust::prelude::*;
use log::LevelFilter;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let console = Console::new().shared();
    RichLogger::new(console)
        .level(LevelFilter::Info)
        .show_path(true)
        .init()?;

    log::info!("Server started");
    Ok(())
}

Note: log macros come from the log crate; add log = "0.4" to your Cargo.toml.

Tracing: enable rich_rust feature tracing and install RichTracingLayer if you use the tracing ecosystem.

HTML/SVG Export

Export terminal output to shareable files:

use rich_rust::prelude::*;

let mut console = Console::new();
console.begin_capture();
console.print("[bold green]Hello[/]");

let html = console.export_html(false);  // false = don't clear buffer
let svg = console.export_svg(true);     // true = clear buffer after

Note: The HTML/SVG exports follow Python Rich's export templates (including optional terminal-window chrome). SVG is rendered with SVG primitives (<text>, <rect>, clip paths), so it works in browsers and in many SVG-capable viewers (no <foreignObject> required).

For a quick demo of export capabilities, run:

cargo run --bin demo_showcase --features showcase -- --export

Syntax Highlighting (requires syntax feature)

use rich_rust::prelude::*;

let code = r#"fn main() { println!("Hello"); }"#;
let syntax = Syntax::new(code, "rust")
    .line_numbers(true)
    .theme("Solarized (dark)");

console.print_renderable(&syntax);

Markdown Rendering (requires markdown feature)

use rich_rust::prelude::*;

let md = Markdown::new("# Header\n\nParagraph with **bold**.");
console.print_renderable(&md);

Pretty / Inspect

Rust doesn't have Python

Extension points exported contracts — how you extend this code

Renderable (Interface)
Trait for objects that can be rendered to the console. [30 implementers]
src/renderables/mod.rs
Scene (Interface)
A single showcase scene. Scenes are self-contained demonstrations of rich_rust features. Each scene has a unique name, [16 …
src/bin/demo_showcase/scenes.rs
TestCase (Interface)
A test case that can be used for integration tests, conformance, and benchmarks. [8 implementers]
tests/conformance/mod.rs
RichCast (Interface)
Rust equivalent of Python Rich's `__rich__` hook. In Python, `rich.protocol.rich_cast(obj)` repeatedly calls `obj.__ric [4 …
src/protocol.rs
Highlighter (Interface)
A highlighter modifies a [`Text`] in-place by adding style spans. This mirrors Python Rich's `Highlighter.highlight(tex [3 …
src/highlighter.rs
RichMeasure (Interface)
Trait for renderables that can provide a measurement. [3 implementers]
src/measure.rs
RenderHook (Interface)
Hook for intercepting rendered segments before output. [1 implementers]
src/console.rs
RenderableMeasure (Interface)
(no doc) [1 implementers]
src/renderables/constrain.rs

Core symbols most depended-on inside this repo

init_test_logging
called by 650
tests/common/mod.rs
clone
called by 574
src/console.rs
print
called by 468
src/console.rs
parse
called by 408
src/bin/demo_showcase.rs
push
called by 395
src/renderables/group.rs
build
called by 393
src/console.rs
arg
called by 310
tests/demo_showcase_harness.rs
with_column
called by 291
src/renderables/table.rs

Shape

Function 3,122
Method 1,126
Class 183
Enum 48
Interface 10

Languages

Rust100%
Python1%

Modules by API surface

src/console.rs245 symbols
src/interactive.rs141 symbols
src/text.rs136 symbols
src/style.rs133 symbols
src/renderables/progress.rs119 symbols
src/renderables/table.rs108 symbols
src/theme.rs94 symbols
src/live.rs87 symbols
src/color.rs78 symbols
src/renderables/traceback.rs77 symbols
src/renderables/layout.rs77 symbols
tests/e2e_markdown.rs73 symbols

For agents

$ claude mcp add rich_rust \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page