| Crates.io | fusabi-tui-render |
| lib.rs | fusabi-tui-render |
| version | 0.2.0 |
| created_at | 2025-12-15 03:22:02.503767+00 |
| updated_at | 2025-12-29 16:53:14.589196+00 |
| description | Renderer abstraction for Fusabi TUI |
| homepage | |
| repository | https://github.com/fusabi-lang/fusabi-tui-runtime |
| max_upload_size | |
| id | 1985474 |
| size | 45,886 |
Renderer abstraction for the Fusabi TUI framework.
This crate provides a unified renderer interface supporting multiple backends, enabling the same TUI code to run standalone in a terminal or as a Scarab plugin via shared memory.
Renders to standard terminals using the crossterm library. Supports all major platforms (Linux, macOS, Windows).
use fusabi_tui_render::prelude::*;
use fusabi_tui_core::{buffer::Buffer, layout::Rect};
use std::io::stdout;
fn main() -> Result<()> {
let mut renderer = CrosstermRenderer::new(stdout())?;
let size = renderer.size()?;
let mut buffer = Buffer::new(Rect::new(0, 0, size.width, size.height));
// Draw to buffer...
renderer.draw(&buffer)?;
renderer.flush()?;
renderer.cleanup()?;
Ok(())
}
In-memory renderer for unit testing TUI applications:
use fusabi_tui_render::test::TestRenderer;
use fusabi_tui_render::renderer::Renderer;
use fusabi_tui_core::{buffer::Buffer, layout::Rect, style::Style};
let mut renderer = TestRenderer::new(10, 5);
let mut buffer = Buffer::new(Rect::new(0, 0, 10, 5));
buffer.set_string(0, 0, "Test", Style::default());
renderer.draw(&buffer).unwrap();
// Verify the output
assert_eq!(renderer.buffer().get(0, 0).unwrap().symbol(), "T");
Renders to Scarab's shared memory for plugin mode. See the fusabi-tui-scarab crate.
use fusabi_tui_render::prelude::*;
use fusabi_tui_core::{buffer::Buffer, layout::Rect, style::{Color, Style}};
use std::io::stdout;
fn main() -> Result<()> {
// Initialize renderer
let mut renderer = CrosstermRenderer::new(stdout())?;
// Get terminal size
let size = renderer.size()?;
let mut buffer = Buffer::new(Rect::new(0, 0, size.width, size.height));
// Draw content
let style = Style::new().fg(Color::Green);
buffer.set_string(0, 0, "Hello, Fusabi TUI!", style);
// Render and flush
renderer.draw(&buffer)?;
renderer.flush()?;
// Cleanup on exit
renderer.cleanup()?;
Ok(())
}
use fusabi_tui_render::prelude::*;
use std::time::Duration;
use std::io::stdout;
fn main() -> Result<()> {
let mut renderer = CrosstermRenderer::new(stdout())?;
loop {
// Poll for events with timeout
if let Some(event) = renderer.poll_event(Duration::from_millis(100)) {
match event {
Event::Key(key_event) => {
if key_event.code == KeyCode::Char('q') {
break;
}
}
Event::Resize(width, height) => {
// Handle terminal resize
}
_ => {}
}
}
// Render frame...
}
renderer.cleanup()?;
Ok(())
}
The core Renderer trait provides a simple, flexible interface:
pub trait Renderer {
type Error: std::error::Error;
/// Draw a buffer to the renderer
fn draw(&mut self, buffer: &Buffer) -> Result<(), Self::Error>;
/// Flush pending changes to the display
fn flush(&mut self) -> Result<(), Self::Error>;
/// Get the current size of the rendering area
fn size(&self) -> Result<Size, Self::Error>;
/// Poll for input events (optional, returns None if not supported)
fn poll_event(&mut self, timeout: Duration) -> Option<Event> {
None
}
/// Cleanup resources (called on shutdown)
fn cleanup(&mut self) -> Result<(), Self::Error>;
}
crossterm-backend (default)Enables the CrosstermRenderer for standalone terminal rendering.
[dependencies]
fusabi-tui-render = "0.1"
For minimal dependencies or when using only the test renderer:
[dependencies]
fusabi-tui-render = { version = "0.1", default-features = false }
All renderers use the RenderError type for error handling:
use fusabi_tui_render::prelude::*;
match renderer.draw(&buffer) {
Ok(_) => {}
Err(RenderError::IoError(e)) => {
eprintln!("IO error: {}", e);
}
Err(RenderError::CrosstermError(e)) => {
eprintln!("Crossterm error: {}", e);
}
Err(e) => {
eprintln!("Other error: {}", e);
}
}
The test renderer makes it easy to test TUI applications:
use fusabi_tui_render::test::TestRenderer;
use fusabi_tui_render::renderer::Renderer;
use fusabi_tui_core::{buffer::Buffer, layout::Rect, style::{Color, Style}};
#[test]
fn test_rendering() {
let mut renderer = TestRenderer::new(20, 10);
let mut buffer = Buffer::new(Rect::new(0, 0, 20, 10));
// Render a colored box
let style = Style::new().bg(Color::Blue);
buffer.set_style(Rect::new(0, 0, 20, 10), style);
renderer.draw(&buffer).unwrap();
// Verify background color
let cell = renderer.buffer().get(5, 5).unwrap();
assert_eq!(cell.bg(), Color::Blue);
}
This crate is designed to work seamlessly with:
See the workspace examples directory for complete applications.
Licensed under either of:
at your option.