| Crates.io | rdx-stderr |
| lib.rs | rdx-stderr |
| version | 0.8.4 |
| created_at | 2025-07-30 18:30:20.90349+00 |
| updated_at | 2025-08-12 18:23:26.505336+00 |
| description | The Rustadex Stderr Package. An opinionated, ergonomic library for pretty-okay CLI terminal output, made of sticks bubble gum and vintage bash scripts. |
| homepage | |
| repository | https://github.com/rustadex/stderr |
| max_upload_size | |
| id | 1773881 |
| size | 614,420 |
rdx-stderr)An opinionated, ergonomic library for pretty-okay CLI terminal output, made of sticks bubble gum and vintage bash scripts.
rdx-stderr is a Rust logging library inspired by years of handcrafted Bash scripts, designed to make your CLI applications beautiful and informative. It provides semantic logging functions, rich formatting utilities, and sophisticated tracing capabilities.
๐ Hierarchical Tracing: Visual function call trees with automatic entry/exit
๐จ Rich Formatting: Tables, banners, boxes with customizable styling
๐ง Interactive Elements: Confirmations, prompts with intelligent defaults
โ๏ธ Modular Architecture: Use only what you need via Cargo features
๐ Context Management: Smart banners for state changes
๐ญ Customizable Glyphs: Unicode symbols that work everywhere
Add to your Cargo.toml:
[dependencies]
rdx-stderr = "0.8.2"
# Or with specific features:
rdx-stderr = { version = "0.8.2", features = ["trace", "interactive", "formatting"] }
use rdx_stderr::Stderr;
let mut log = Stderr::new();
log.info("Hello, world!");
log.warn("Something's not quite right");
log.okay("All systems go!");
use rdx_stderr::{Stderr, qtrace_fn};
let mut log = Stderr::new();
qtrace_fn!("parse_config", "starting configuration parsing");
qtrace_fn!("parse_config", "loaded 42 settings");
qtrace_fn!("validate_config", "checking required fields");
qtrace_fn!("validate_config", "validation successful");
use rdx_stderr::logger;
fn main() {
logger.info("This works from anywhere!");
logger.warn("Watch out!");
}
Stderr logger or global logger๐ญ 80+ configurable Unicode glyphs
๐จ Custom color schemes
๐ท๏ธ Application labeling
โ๏ธ Runtime configuration toggles
rdx-stderr uses Cargo features for modular functionality:
default: Includes all features (trace, interactive, formatting, auto-fn-names)minimal: Just core logging functionalitytrace: Hierarchical function tracing with visual tree structureinteractive: User prompts, confirmations, and interactive elementsformatting: Tables, boxes, banners, and advanced text formattingauto-fn-names: Automatic function name detection for tracing# Minimal build - just basic logging
rdx-stderr = { version = "0.8.2", default-features = false, features = ["minimal"] }
# Full-featured build
rdx-stderr = { version = "0.8.2", features = ["default"] }
src/
โโโ lib.rs # Main library interface
โโโ rdx/
โ โโโ stderr.rs # Core module with feature re-exports
โ โโโ esc/ # Colors, glyphs, styling
โ โ โโโ colors.rs
โ โ โโโ glyphs.rs
โ โ โโโ style.rs
โ โ โโโ boxes.rs
โ โโโ utils/ # Utilities and helpers
โ โ โโโ helpers.rs
โ โ โโโ flag.rs
โ โ โโโ grid.rs
โ โโโ stderr/ # Feature implementations
โ โ โโโ stderr.rs # Core logging
โ โ โโโ trace.rs # Hierarchical tracing
โ โ โโโ interactive.rs # Prompts & confirmations
โ โ โโโ formatting.rs # Tables, banners, boxes
โ โ โโโ static_logger.rs # Global logger
โ โโโ macros.rs # Convenience macros
โ โโโ meta.rs # Version and help info
โโโ examples/ # Usage demonstrations
The modular architecture allows you to include only what you need:
Core (stderr.rs): Always available - basic logging functions
Trace Extension: Hierarchical function call tracking
Interactive Extension: User prompts and confirmations
Formatting Extension: Tables, banners, and advanced layout
Auto Function Names: Automatic function name detection
# Enable different message types
export TRACE_MODE=0 # Show trace messages
export DEBUG_MODE=0 # Show debug messages
export DEV_MODE=0 # Show dev messages
export SILLY_MODE=0 # Show magic/silly messages
export QUIET_MODE=0 # Enable quiet mode
# Run your application
cargo run
Track function calls with visual hierarchy:
use rdx_stderr::{qtrace_fn, qtrace_auto, qtrace_scope};
fn process_data() {
qtrace_fn!("process_data", "starting data processing");
parse_input();
validate_data();
qtrace_fn!("process_data", "processing complete");
}
fn parse_input() {
qtrace_auto!("parsing user input"); // Uses function name automatically
// Scoped tracing with automatic entry/exit
qtrace_scope!("validation", {
qtrace_auto!("checking format");
qtrace_auto!("format valid");
});
}
Output:
ฮป process_data: starting data processing
โโ ฮป parse_input: parsing user input
โ โโ ฮป validation: checking format
โ โโ ฮป validation: format valid
โโ ฮป process_data: processing complete
use rdx_stderr::Stderr;
let mut log = Stderr::new();
log.simple_table(&[
&["Name", "Age", "City"],
&["Alice", "30", "New York"],
&["Bob", "25", "San Francisco"],
&["Charlie", "35", "Chicago"],
])?;
log.banner("System Status", '=')?;
log.boxed("CRITICAL: System maintenance in progress")?;
// Smart context management - only shows banner when context changes
log.set_context("@myapp.VAR.config");
log.info("First operation"); // Shows context banner
log.info("Second operation"); // No banner (same context)
log.set_context("@myapp.VAR.secrets");
log.info("Third operation"); // Shows new context banner
if log.confirm("Delete all files?")?.unwrap_or(false) {
log.warn("Deleting files...");
} else {
log.info("Operation cancelled");
}
let critical = "ERASE DISK?\nThis action cannot be undone.";
if log.confirm_builder(critical)
.boxed(true)
.style(BorderStyle::Heavy)
.ask()?
.unwrap_or(false) {
log.error("Proceeding with disk erasure");
}
Create your own visual style:
use rdx_stderr::{Stderr, GlyphSet, LogLevel};
// Custom emoji glyphs
let custom_glyphs = GlyphSet {
info: "๐",
warn: "โ ๏ธ",
error: "โ",
okay: "โ
",
trace: "๐",
debug: "๐",
magic: "โจ",
};
let mut log = Stderr::new().with_glyphs(custom_glyphs);
log.info("Info with custom emoji glyph");
// Or set individual glyphs
log.set_glyph(LogLevel::Info, "๐");
log.info("Info with rocket glyph");
Quick logging with macros:
use rdx_stderr::{qinfo, qwarn, qerror, qpretty};
qinfo!("System started successfully");
qwarn!("Configuration file not found");
qerror!(my_error_struct); // Auto pretty-prints Debug types
qpretty!("โก", &complex_data); // Boxed, multiline pretty-dump
Beautiful debug output for any type implementing Debug:
#[derive(Debug)]
struct AppState {
count: u32,
active: bool,
users: Vec<String>
}
let state = AppState {
count: 42,
active: true,
users: vec!["alice".into(), "bob".into()]
};
// Pretty debug output
log.info_debug(&state);
// Inspection interface
log.inspect().warn(&state);
Rich color and styling support:
use rdx_stderr::{Color, Glyph, Style};
let mut log = Stderr::new();
// Built-in semantic colors
log.okay("Success message in green");
log.warn("Warning message in yellow");
log.error("Error message in red");
// Custom glyphs
println!("Chess piece: {}", Glyph::PAWN);
println!("Arrow: {}", Glyph::ARROW_RIGHT);
use rdx_stderr::Stderr;
fn main() {
let mut log = Stderr::new();
log.info("Starting application");
match process_files() {
Ok(count) => log.okay(&format!("Processed {} files", count)),
Err(e) => {
log.error(&format!("Processing failed: {}", e));
std::process::exit(1);
}
}
}
use rdx_stderr::{Stderr, qtrace_fn};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut log = Stderr::new();
log.banner("File Processor v1.0", '=')?;
qtrace_fn!("main", "application started");
// Show processing status
log.simple_table(&[
&["File", "Status", "Lines"],
&["config.toml", "โ", "42"],
&["data.json", "โ", "156"],
&["README.md", "โ", "89"],
])?;
if log.confirm("Process all files?")?.unwrap_or(false) {
qtrace_fn!("main", "user confirmed processing");
log.okay("All files processed successfully!");
} else {
log.warn("Processing cancelled by user");
}
Ok(())
}
use stderr::Stderr;
fn main() {
let mut log = Stderr::new();
log.trace_fn("parse_config", "starting configuration");
log.trace_fn("parse_config", "reading config file");
log.trace_fn("validate_settings", "checking database URL");
log.trace_fn("validate_settings", "database connection OK");
log.trace_fn("parse_config", "configuration complete");
}
Output:
ฮปโโโ[parse_config]
โ
โโโ> starting configuration
โโโ>> reading config file
ฮปโโโ[validate_settings]
โ
โโโ> checking database URL
โโโ>> database connection OK
ฮปโโโ[parse_config]
โ
โโโ>> configuration complete
use stderr::{Stderr, qtrace_auto};
#[cfg(feature = "auto-fn-names")]
fn my_function() {
qtrace_auto!("This automatically shows 'my_function' as the function name");
qtrace_auto!("Performing some work");
nested_function();
qtrace_auto!("Work complete");
}
#[cfg(feature = "auto-fn-names")]
fn nested_function() {
qtrace_auto!("Inside nested function");
}
use stderr::Stderr;
fn complex_operation() {
let mut log = Stderr::new();
let mut scope = log.trace_scope("complex_operation");
scope.step("initializing resources");
scope.step("processing data");
scope.step_debug("intermediate result", &some_data);
scope.step("finalizing");
// Automatic exit trace when scope is dropped
}
use stderr::Stderr;
fn main() {
let mut log = Stderr::new();
log.trace_add("Creating new user account");
log.trace_found("Located existing preferences");
log.trace_item("Processing item #42");
log.trace_done("User account setup complete");
log.trace_sub("Cleaning up temporary files");
}
use stderr::Stderr;
fn main() {
let mut log = Stderr::new();
// First context - shows banner
log.set_context("@myapp.VAR.config");
log.info("Working in config context");
// Same context - no banner
log.set_context("@myapp.VAR.config");
log.info("Still in config context");
// Different context - shows new banner
log.set_context("@myapp.VAR.secrets");
log.warn("Switched to secrets context");
// Clear context
log.clear_context();
log.info("Back to neutral context");
}
Output:
โญโโโโโโโ Context: @myapp.VAR.config โโโโโโโโฎ
[ฮป] Working in config context
[ฮป] Still in config context
โญโโโโโโโ Context: @myapp.VAR.secrets โโโโโโโฎ
[โณ] Switched to secrets context
[ฮป] Back to neutral context
use stderr::Stderr;
fn main() {
let mut log = Stderr::new();
log.set_context("@main.VAR.config");
log.info("In main context");
// Temporary context without changing persistent cursor
log.with_context("@temp.VAR.test", || {
log.info("Temporary operation");
log.warn("This won't change the main context");
});
log.info("Back in main context");
}
use stderr::Stderr;
fn main() -> std::io::Result<()> {
let mut log = Stderr::new();
log.simple_table(&[
&["Name", "Type", "Size", "Modified"],
&["config.env", "file", "1.2KB", "2024-01-15"],
&["secrets/", "dir", "--", "2024-01-14"],
&["api_keys.json", "file", "856B", "2024-01-13"],
])?;
Ok(())
}
use stderr::Stderr;
fn main() -> std::io::Result<()> {
let mut log = Stderr::new();
let items = [
"config", "secrets", "api_keys", "database",
"redis", "jwt", "oauth", "webhooks",
"logging", "monitoring", "alerts", "backup"
];
log.columns(&items, 4)?;
Ok(())
}
use stderr::{Stderr, BorderStyle, flag_table, term_width};
fn main() {
let mut log = Stderr::new();
let flags: u32 = 0b1010_1100_0011_0101;
let labels = &[
"READ", "WRITE", "EXEC", "DELETE",
"CREATE", "UPDATE", "LIST", "ADMIN",
"DEBUG", "TRACE", "BACKUP", "RESTORE",
"MONITOR", "ALERT", "SYNC", "ASYNC
src/
โโโ lib.rs # Main library interface
โโโ rdx/
โ โโโ stderr.rs # Core module with feature re-exports
โ โโโ esc/ # Colors, glyphs, styling
โ โ โโโ colors.rs
โ โ โโโ glyphs.rs
โ โ โโโ style.rs
โ โ โโโ boxes.rs
โ โโโ utils/ # Utilities and helpers
โ โ โโโ helpers.rs
โ โ โโโ flag.rs
โ โ โโโ grid.rs
โ โโโ stderr/ # Feature implementations
โ โ โโโ stderr.rs # Core logging
โ โ โโโ trace.rs # Hierarchical tracing
โ โ โโโ interactive.rs # Prompts & confirmations
โ โ โโโ formatting.rs # Tables, banners, boxes
โ โ โโโ static_logger.rs # Global logger
โ โโโ macros.rs # Convenience macros
โ โโโ meta.rs # Version and help info
โโโ examples/ # Usage demonstrations
The library includes comprehensive test drivers and examples:
# Run all examples
cargo run --example trace_driver --all-features
cargo run --example interactive_driver --all-features
cargo run --example formatting_driver --all-features
# Test specific features
cargo test --features trace
cargo test --features interactive
cargo test --features formatting
rdx-stderr is actively used by:
Using rdx-stderr in your project? Let us know!
This project is licensed under either of:
at your option.