# Fusabi TUI
> Terminal UI library for Fusabi - providing Ratatui bindings and widgets
[](https://crates.io/crates/fusabi-tui)
[](https://docs.rs/fusabi-tui)
[](LICENSE-MIT)
## Overview
`fusabi-tui` is a Rust library that exposes the powerful [Ratatui](https://ratatui.rs/) terminal UI framework to [Fusabi](https://github.com/fusabi-lang/fusabi) scripts (F# for configuration). This enables rich, interactive terminal interfaces to be built declaratively using F# syntax.
**Status**: Production-ready - Extracted from Hibana project, fully tested and documented
## Features
- **Widget Library**: High-level UI components (lists, tables, charts, gauges, etc.)
- **Layout System**: Flexbox-like constraint-based layout engine
- **Canvas API**: Low-level drawing primitives for custom visualizations
- **Fusabi Integration**: Seamless bindings for F# scripts
- **Type Safe**: Leverages Rust's type system for compile-time guarantees
- **Performance**: Zero-copy where possible, optimized for low-latency rendering
## Quick Start
### Installation
Add to your `Cargo.toml`:
```toml
[dependencies]
fusabi-tui = "0.1.0"
```
### Rust Usage
#### Basic Table
```rust
use fusabi_tui::widgets::{TableData, ColumnDef, render_table};
use ratatui::layout::Constraint;
let columns = vec![
ColumnDef {
header: "GPU".to_string(),
width: Constraint::Length(10),
},
ColumnDef {
header: "Utilization".to_string(),
width: Constraint::Length(15),
},
];
let rows = vec![
vec!["GPU 0".to_string(), "85%".to_string()],
vec!["GPU 1".to_string(), "92%".to_string()],
];
let table = TableData::new(columns, rows)
.title("GPU Stats")
.borders(true);
// In your render loop:
frame.render_widget(render_table(&table), area);
```
#### Graph Visualization
```rust
use fusabi_tui::canvas::{GraphCanvas, GraphData, GraphNode, GraphEdge};
let mut graph = GraphData::new();
// Add nodes
graph.add_node(GraphNode::builder()
.id("source")
.label("Data Source")
.position(0.0, 0.0)
.build());
graph.add_node(GraphNode::builder()
.id("sink")
.label("Data Sink")
.position(10.0, 5.0)
.selected(true) // Highlight this node
.build());
// Add edges
graph.add_edge(GraphEdge::new("source", "sink")
.label("1.5K events/s"));
// Render
let canvas = GraphCanvas::new(&graph, None); // Auto-calculate bounds
frame.render_widget(canvas, area);
```
#### Formatting Utilities
```rust
use fusabi_tui::formatting::{format_number, format_bytes, format_latency, format_duration};
use std::time::Duration;
// Format large numbers with K/M/B/T suffixes
assert_eq!(format_number(1_500), "1.50K");
assert_eq!(format_number(2_500_000), "2.50M");
assert_eq!(format_number(3_000_000_000), "3.00B");
// Format byte sizes with appropriate units
assert_eq!(format_bytes(1024), "1.00 KB");
assert_eq!(format_bytes(1_048_576), "1.00 MB");
assert_eq!(format_bytes(1_073_741_824), "1.00 GB");
// Format latency (input in microseconds)
assert_eq!(format_latency(500), "500μs");
assert_eq!(format_latency(1_500), "1.50ms");
assert_eq!(format_latency(2_000_000), "2.00s");
// Format duration (input as std::time::Duration)
assert_eq!(format_duration(Duration::from_secs(45)), "45s");
assert_eq!(format_duration(Duration::from_secs(125)), "2m 5s");
assert_eq!(format_duration(Duration::from_secs(3665)), "1h 1m");
```
### Fusabi Script Usage
```fsharp
// From a Fusabi script (.fsx)
open Fusabi.TUI
// Create a simple list widget
let list = List.create [
"Item 1"
"Item 2"
"Item 3"
]
// Define a vertical layout
let layout = Layout.vertical [
Constraint.Percentage 50
Constraint.Min 10
]
```
## Architecture
The library is organized into five main modules:
### 1. Widgets (`src/widgets/`)
Provides type-safe builders for Ratatui widgets:
- **List**: Scrollable lists with selection
- **Table**: Multi-column tabular data
- **Gauge**: Progress indicators
- **Chart**: Line and bar charts
- **Paragraph**: Multi-line text blocks
- **Block**: Containers with borders and titles
### 2. Layouts (`src/layouts/`)
Constraint-based layout system for dividing terminal space:
- **Percentage**: Proportional allocation
- **Ratio**: Fractional allocation
- **Length**: Fixed size in characters
- **Min/Max**: Flexible sizing with bounds
### 3. Canvas (`src/canvas/`)
Low-level drawing primitives for custom graphics:
- Shape rendering (rectangles, circles, lines)
- Coordinate mapping (world space to canvas space)
- Custom paint functions
- High-resolution Braille patterns
### 4. Formatting (`src/formatting/`)
Human-readable formatting utilities for common data types:
- **Numbers**: Large number formatting (K/M/B suffixes)
- **Bytes**: Memory size formatting (B/KB/MB/GB)
- **Time**: Duration and latency formatting (s/ms/μs)
```rust
use fusabi_tui::{format_number, format_bytes, format_latency};
println!("{}", format_number(1_500_000)); // "1.50M"
println!("{}", format_bytes(2048)); // "2.00 KB"
println!("{}", format_latency(1500)); // "1.50ms"
```
### 5. Bindings (`src/bindings/`)
Fusabi VM integration layer:
- Native function registration
- Type marshaling between F# and Rust
- Error handling and conversion
## Development Status
### Completed ✅
- ✅ Repository scaffold and directory structure
- ✅ Module organization (widgets, layouts, canvas, formatting, bindings)
- ✅ Cargo.toml with feature flags (`bindings` feature)
- ✅ Complete documentation (rustdoc + README)
- ✅ **Table widget** - Full implementation with builders
- ✅ **Formatting utilities** - Numbers, bytes, latency, duration (20 tests)
- ✅ **Canvas system** - Graph rendering with nodes and edges (27 tests)
- ✅ **Layout utilities** - Constraint-based layout system
- ✅ **Fusabi bindings** - Native function registration (optional feature)
- ✅ **59 unit tests** - All passing
- ✅ **4 working examples** - Demonstrating all features
- ✅ **Performance benchmarks** - Criterion-based
- ✅ **Integration tests** - Testing module interactions
### Test Coverage
```
Total Tests: 59
- Canvas tests: 27 (nodes, edges, bounds, graph rendering)
- Formatting tests: 20 (numbers, bytes, time formatting)
- Widget tests: 10 (table rendering, column definitions)
- Library tests: 2 (version, module structure)
```
### Code Statistics
- Source code: 2,890 lines
- Examples: 549 lines
- Tests: 59 unit tests
- Total: ~3,460 lines
## Examples
See the `examples/` directory for working demonstrations:
- **`simple_list.rs`**: Basic list widget usage and rendering
- **`layout_demo.rs`**: Constraint-based layout system demonstration
- **`graph_demo.rs`**: Interactive graph visualization with nodes and edges
- **`table_demo.rs`**: Table widget with multiple columns and data rows
Run examples with:
```bash
cargo run --example formatting_demo
cargo run --example graph_demo
cargo run --example table_demo
```
## Features
### Feature Flags
The library supports optional features via Cargo feature flags:
```toml
[dependencies]
fusabi-tui = { version = "0.1.0", features = ["bindings"] }
```
**Available features**:
- `bindings` - Enables Fusabi VM integration (requires `fusabi` dependency)
- Provides `FusabiTuiModule` for registering native functions
- Allows F# scripts to call formatting and widget functions
- Default: enabled
To use the library without Fusabi integration:
```toml
[dependencies]
fusabi-tui = { version = "0.1.0", default-features = false }
```
### Known Limitations
1. **Fusabi Bindings**: The `bindings` module currently has limitations due to Fusabi's `Rc<RefCell<T>>` design (not `Send+Sync`). Full widget lifecycle management from F# scripts is not yet supported. Currently available:
- Formatting functions (fully functional)
- Widget specifications (JSON-serializable structures)
2. **Layout System**: The `layouts` module is currently a stub. Full constraint-based layout is planned for v0.2.0.
3. **Widget Coverage**: Currently implemented widgets:
- ✅ Table
- ✅ Canvas (Graph)
- 📋 List (planned)
- 📋 Gauge (planned)
- 📋 Chart (planned)
## Integration Guide
### Using in Your Project
1. **Add dependency**:
```toml
[dependencies]
fusabi-tui = { path = "../fusabi-tui" } # Or version from crates.io
ratatui = "0.28"
```
2. **Import types**:
```rust
use fusabi_tui::{
formatting::{format_number, format_bytes, format_latency, format_duration},
widgets::{TableData, ColumnDef, render_table},
canvas::{GraphCanvas, GraphData, GraphNode, GraphEdge},
};
```
3. **Use in render loop**:
```rust
use ratatui::prelude::*;
use fusabi_tui::widgets::render_table;
fn ui(frame: &mut Frame, table_data: &TableData) {
let area = frame.size();
frame.render_widget(render_table(table_data), area);
}
```
### With Fusabi Scripts
If you're using the `bindings` feature:
```rust
use fusabi_tui::bindings::FusabiTuiModule;
use fusabi::Engine;
let mut engine = Engine::new();
let tui_module = FusabiTuiModule::new();
tui_module.register(&mut engine)?;
// Now F# scripts can call:
// - tui_format_number(n: int) -> string
// - tui_format_bytes(bytes: int) -> string
// - tui_format_latency(us: int) -> string
// - tui_format_duration(secs: int) -> string
```
## Testing
```bash
# Run all tests
cargo test
# Run with output
cargo test -- --nocapture
# Run benchmarks
cargo bench
```
## Documentation
### API Documentation
Generate and view the full API documentation:
```bash
cargo doc --open
```
### Guides and References
- **Current Documentation** (latest development):
- [Fusabi Bindings Guide](docs/FUSABI_BINDINGS.md)
- [Architecture Overview](ARCHITECTURE.md)
- [Documentation Structure](docs/STRUCTURE.md)
- [Release Process](docs/RELEASE.md)
- **Versioned Documentation**:
- [v0.2.0](docs/versions/v0.2.0/) - Current stable release
- Future versions will be added to `docs/versions/` as they are released
### Plugin Runtime Integration
This library is designed to work with:
- **fusabi-plugin-runtime** - For TUI extensibility and plugin demos
- **fusabi-stdlib-ext** - For terminal helper functions in examples
- **Phage policy integration** - For script/doc policy enforcement
For detailed integration patterns, see [Plugin Runtime Integration Guide](docs/PLUGIN_RUNTIME_INTEGRATION.md).
## Contributing
This is part of the Raibid Labs ecosystem. Contributions welcome!
1. Ensure all tests pass: `cargo test`
2. Format code: `cargo fmt`
3. Check lints: `cargo clippy -- -D warnings`
4. Update documentation as needed
## Related Projects
- **[Hibana](../hibana)**: GPU observability agent (parent project)
- **[Fusabi](https://github.com/fusabi-lang/fusabi)**: F# scripting runtime
- **[Ratatui](https://ratatui.rs/)**: Underlying TUI framework
## License
Licensed under either of:
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE))
- MIT license ([LICENSE-MIT](LICENSE-MIT))
at your option.
## Acknowledgments
- Built on top of the excellent [Ratatui](https://ratatui.rs/) library
- Inspired by the [Fusabi](https://github.com/fusabi-lang/fusabi) project
- Extracted from the [Hibana](../hibana) GPU observability agent
---
**Version**: 0.1.0
**Last Updated**: 2025-01-26