Expand description
§Bluegum
A beautiful tree printer for Rust that renders trees in a single pass with rich formatting and customization options.
Initially designed to handle concrete and abstract syntax trees, it excels at complex data structures with nested nodes and fields. The output is designed to be both human-readable and diff-friendly, with consistent formatting and optional line numbers.
§Quick Start
use bluegum::{
Bluegum,
Builder,
};
// Implement Bluegum for your type
struct MyData {
name: String,
value: i32,
}
impl Bluegum for MyData {
fn node(&self, b: &mut Builder) {
b.name("MyData")
.field("name", &self.name)
.field("value", &self.value);
}
}
let data = MyData {
name: "example".to_string(),
value: 42,
};
// Print to stdout with colors
bluegum::println(&data);
// Or render to string without colors
let output = bluegum::render(&data);§Output Format
Bluegum generates tree-like output with sophisticated formatting:
- Line numbers for easy reference
- Unicode box-drawing characters for tree structure
- Colored output (when supported)
- Fields displayed as key-value pairs
- Alternate values aligned in a separate column
- Debug information in brackets on the right
Example output showing all features:
00│◈─▣ symbol::Ident
01│ │ · modifier: Capitalised Sum [value: Spur(3)]
02│ │ · line: 2 actual [file: main.rs]§Unique Features
§Alternate Values (alt)
Every field can have an alternate value displayed in a right-aligned column. This is particularly useful for showing original source text alongside structured data:
use bluegum::{
Bluegum,
Builder,
};
struct Token {
token_type: String,
source_text: String,
line: u32,
}
impl Bluegum for Token {
fn node(&self, b: &mut Builder) {
b.name("Token")
.field("type", &self.token_type)
.alt(&self.source_text) // Shows the actual source text
.field("line", self.line);
}
}§Debug Information (debug)
Multiple key-value debug pairs can be attached to any field or node, displayed in brackets on the far right:
use bluegum::{
Bluegum,
Builder,
};
struct Symbol {
name: String,
id: u32,
scope: String,
}
impl Bluegum for Symbol {
fn node(&self, b: &mut Builder) {
b.name("Symbol")
.field("name", &self.name)
.debug("id", self.id)
.debug("scope", &self.scope);
}
}§Flexible Tree Structure
The tree structure you display doesn’t need to match your data structure. This is powerful for:
- Reconstructing trees from adjacency lists
- Showing logical relationships that differ from memory layout
- Creating custom views of complex data structures
- Flattening or restructuring for better visualization
use bluegum::{
Bluegum,
Builder,
};
// Data stored as flat list, but displayed as tree
struct FlatData {
items: Vec<(String, Option<usize>)>, // (name, parent_index)
}
impl Bluegum for FlatData {
fn node(&self, b: &mut Builder) {
b.name("FlatData");
// Create tree structure from flat data
for (i, (name, parent)) in self.items.iter().enumerate() {
if parent.is_none() {
b.field("root", name);
}
}
}
}§Key Features
- Single Pass Rendering: Efficient memory usage with one-pass traversal
- Rich Formatting: Line numbers, Unicode characters, ANSI colors
- Flexible Node Types: Regular nodes, fragments, and leaf nodes
- State-Based Rendering: Support for external context during rendering
- Comprehensive Styling: Full control over appearance and layout
- Built-in Implementations: Ready-to-use implementations for common types
- Extensive Testing: Comprehensive test suite with edge case coverage
§Core Concepts
- Nodes: Individual items in the tree, can have fields and child nodes
- Fields: Key-value pairs displayed within a node
- Builder: Fluent API for constructing tree representations
- State: Optional context for rendering nodes that depend on external data (like symbol tables or type information)
- Styles: Comprehensive customization of colors, spacing, and layout
§Key Features
- Single Pass Rendering: Efficient memory usage with one-pass traversal
- Rich Formatting: Line numbers, Unicode characters, ANSI colors
- Flexible Node Types: Regular nodes, fragments, and leaf nodes
- State-Based Rendering: Support for external context during rendering
- Comprehensive Styling: Full control over appearance and layout
- Built-in Implementations: Ready-to-use implementations for common types
- Extensive Testing: Comprehensive test suite with edge case coverage
§Advanced Usage
§Custom Styling
use {
bluegum::{
Printer,
Styles,
},
owo_colors::Style,
};
let mut styles = Styles::default();
styles.hide_line_numbers = true;
styles.type_name = Style::new().red().bold();
let mut printer = Printer::new(styles);
// Use printer.render() and printer.to_stdout()§State-Based Rendering
For trees that need external context (like symbol tables):
use bluegum::{
Bluegum,
BluegumWithState,
Builder,
};
struct SymbolTable {
names: Vec<String>,
}
struct Variable {
name_id: usize,
}
impl Bluegum for Variable {
fn node(&self, b: &mut Builder) {
b.name("Variable").field("name_id", self.name_id);
}
}
impl BluegumWithState<SymbolTable> for Variable {
fn node_with_state(&self, b: &mut Builder, symbols: &SymbolTable) {
b.name("Variable")
.field("name", &symbols.names[self.name_id])
.alt(format!("id:{}", self.name_id));
}
}Structs§
- Builder
- A fluent builder for constructing tree representations.
- Leaf
- A simple leaf node helper for creating nodes with just fields (no child nodes)
- Printer
- The main printer for rendering
Bluegumtrees to formatted output. - Style
- A pre-computed style that can be applied to a struct using [
OwoColorize::style]. Its interface mimicks that of [OwoColorize], but instead of chaining methods on your object, you instead chain them on theStyleobject before applying it. - Styles
- Configuration for styling the output of tree rendering.
Traits§
- Bluegum
- Implement this trait to render this type and optionally any nodes in a tree-like format.
- Bluegum
With State - A stateful variant of
Bluegumthat allows rendering with external context. - Nodes
- A trait for collections of items that can be rendered as multiple tree nodes.