Crates.io | bug |
lib.rs | bug |
version | 0.3.1 |
created_at | 2025-09-02 02:19:48.924111+00 |
updated_at | 2025-09-03 18:18:42.282558+00 |
description | A simple Rust library for printing an error in the event of a bug and allowing users to easily file a bug report via GitHub issues using bug templates. |
homepage | |
repository | |
max_upload_size | |
id | 1820429 |
size | 83,437 |
A Rust library for streamlined bug reporting that generates GitHub issue URLs with pre-filled templates. Works in both std
and no_std
environments. When bugs occur, bug
prints tracing-style error messages to stderr and provides clean GitHub URLs for easy bug reporting.
include_str!
macro--no-default-features
Add this to your Cargo.toml
:
[dependencies]
bug = "0.2.0"
For embedded or no_std environments:
[dependencies]
bug = { version = "0.2.0", default-features = false }
use bug::{bug, init, IssueTemplate};
fn main() -> Result<(), &'static str> {
// Initialize with your GitHub repository
init("username", "repository")
.add_template("crash", IssueTemplate::new(
"Application Crash: {error_type}",
"## Description\nThe application crashed with error: {error_type}\n\n## Context\n- Function: {function}\n- Line: {line}"
).with_labels(vec!["bug".to_string(), "crash".to_string()]))
.build()?;
// Later in your code, when a bug occurs:
let url = bug!("crash", {
error_type = "NullPointerException",
function = "calculate_sum",
line = "42"
});
println!("Bug report URL: {}", url);
Ok(())
}
This outputs:
๐ BUG ENCOUNTERED in src/main.rs:15
Template: crash
Parameters:
error_type: NullPointerException
function: calculate_sum
line: 42
File a bug report: https://github.com/username/repository/issues/new?title=Application%20Crash%3A%20NullPointerException&body=...
For no_std
environments or when you prefer not to use global state, use the handle-based API:
use bug::{bug_with_handle, init_handle, IssueTemplate, FxHashMap};
fn main() {
// Create a handle that doesn't use global state
let bug_handle = init_handle("myorg", "myproject")
.add_template("crash", IssueTemplate::new(
"Application Crash: {error_type}",
"## Description\nThe application crashed with error: {error_type}"
))
.add_template("performance", IssueTemplate::new(
"Performance Issue: {operation} is too slow",
"Operation: {operation}\nExpected: {expected}ms\nActual: {actual}ms"
));
// Use the handle to report bugs
let url = bug_with_handle!(bug_handle, "crash", {
error_type = "NullPointerException"
});
// Or call methods directly with FxHashMap
let mut params = FxHashMap::default();
params.insert("operation".to_string(), "database_query".to_string());
params.insert("expected".to_string(), "100".to_string());
params.insert("actual".to_string(), "1500".to_string());
let direct_url = bug_handle.generate_url("performance", ¶ms).unwrap();
}
In no_std
mode:
FxHashMap
instead of std::collections::HashMap
bug!()
macro returns empty string (use bug_with_handle!()
instead)HyperlinkMode::Always
or Never
explicitly)Output
trait for logging to different targets#[cfg(not(feature = "std"))]
use bug::{Output, BugReportHandle};
struct MyOutput;
impl Output for MyOutput {
fn write_str(&mut self, s: &str) {
// Send to your logging system, UART, etc.
my_log_function(s);
}
fn write_fmt(&mut self, args: core::fmt::Arguments) {
// Format and send to your logging system
my_log_function(&format!("{}", args));
}
}
let mut output = MyOutput;
let url = bug_handle.report_bug_with_output("crash", ¶ms, file!(), line!(), &mut output);
Create structured markdown templates for consistent bug reports:
templates/crash_report.md:
Application Crash: {error_type}
## Description
The application crashed with error: {error_type}
## Context
- Function: {function}
- Line: {line}
- OS: {os}
- Version: {version}
## Steps to Reproduce
1. {step1}
2. {step2}
3. {step3}
## Expected Behavior
{expected_behavior}
## Additional Information
{additional_info}
Load in Rust:
use bug::{init, template_file};
fn main() -> Result<(), &'static str> {
init("myorg", "myproject")
.add_template_file("crash", template_file!("templates/crash_report.md", labels: ["bug", "crash"]))
.build()?;
Ok(())
}
use bug::{init, IssueTemplate, template_file};
fn main() -> Result<(), &'static str> {
init("myorg", "myproject")
// Simple inline template
.add_template("simple", IssueTemplate::new(
"Simple Issue: {title}",
"Description: {description}"
))
// File-based templates with labels
.add_template_file("crash", template_file!("templates/crash_report.md", labels: ["bug", "crash"]))
.add_template_file("performance", template_file!("templates/performance_issue.md", labels: ["performance", "optimization"]))
.build()?;
Ok(())
}
// Performance issue reporting
let url = bug!("performance", {
operation = "database_query",
expected = "100",
actual = "1500",
ratio = "15",
os = std::env::consts::OS,
version = env!("CARGO_PKG_VERSION"),
hardware = "Intel i7-12700K, 32GB RAM",
profiling_data = "CPU: 45%, Memory: 2.1GB, Disk I/O: 150MB/s",
impact_description = "User experience is significantly degraded"
});
// Simple usage without parameters
bug!("error");
The bug!()
macro prints structured information to stderr:
๐ BUG ENCOUNTERED in src/database.rs:127
Template: performance
Parameters:
operation: database_query
expected: 100
actual: 1500
ratio: 15
os: windows
version: 0.1.0
File a bug report: https://github.com/myorg/myproject/issues/new?title=Performance%20Issue...
Generated GitHub URLs can be quite long (800+ characters) due to URL-encoded template content, making log messages verbose and cluttering terminal output. Terminal hyperlink support using ANSI escape sequences to display clean, clickable text while hiding the long URL underneath.
Configure how links are displayed:
use bug::{init, HyperlinkMode};
// Auto-detect terminal hyperlink support (default)
init("user", "repo")
.hyperlinks(HyperlinkMode::Auto)
.build()?;
// Always use hyperlinks
init("user", "repo")
.hyperlinks(HyperlinkMode::Always)
.build()?;
// Never use hyperlinks (show full URLs)
init("user", "repo")
.hyperlinks(HyperlinkMode::Never)
.build()?;
Automatic detection works with:
With Hyperlinks (clean):
๐ BUG ENCOUNTERED in src/main.rs:45
Template: crash
Parameters:
error_type: NullPointerException
function: calculate_sum
File a bug report
Without Hyperlinks (traditional):
๐ BUG ENCOUNTERED in src/main.rs:45
Template: crash
Parameters:
error_type: NullPointerException
function: calculate_sum
File a bug report: https://github.com/user/repo/issues/new?title=Application%20Crash...
The hyperlink text "File a bug report" becomes clickable and opens the full GitHub issue URL when clicked, keeping your logs clean while maintaining full functionality.
init(owner, repo)
- Initialize bug reporting configuration (std only)init_handle(owner, repo)
- Create a bug report handle (std and no_std)bug!(template, {params})
- Report a bug with given template and parameters (std only)bug_with_handle!(handle, template, {params})
- Report bug using handle (std and no_std)create_terminal_hyperlink(url, text)
- Create ANSI hyperlink escape sequencesupports_hyperlinks()
- Detect terminal hyperlink support (std only, no_std returns false)IssueTemplate
- Represents a GitHub issue templateTemplateFile
- File-based template with validationBugReportConfigBuilder
- Fluent API for configuration (std only)BugReportHandle
- Handle-based bug reporting (std and no_std)HyperlinkMode
- Configure hyperlink display behaviorFxHashMap<K, V>
- HashMap type used by the API (re-exported from hashbrown)Output
- Trait for custom output in no_std environmentsHyperlinkMode::Auto
- Auto-detect terminal support (default, std only)HyperlinkMode::Always
- Always use hyperlinksHyperlinkMode::Never
- Always show full URLstemplate_file!(path, labels: [...])
- Load template from filebug!(template, {key = value, ...})
- Report bug with parameters (std only)bug_with_handle!(handle, template, {key = value, ...})
- Report bug with handle (std and no_std)std
(default) - Enable std support with global state and environment detectionstd
is disabled: no_std mode with handle-based API onlySee the examples/
directory for complete working examples:
basic_usage.rs
- Basic global state usagehandle_usage.rs
- Handle-based API (works in no_std)template_file_usage.rs
- File-based templateshyperlink_demo.rs
- Terminal hyperlink examplestemplates/
directoryRun examples:
cargo run --example basic_usage
cargo run --example handle_usage
cargo run --example template_file_usage
For no_std examples:
cargo run --example handle_usage --no-default-features
git checkout -b feature/amazing-feature
)git commit -m 'Add some amazing feature'
)git push origin feature/amazing-feature
)This project is licensed under the MIT License - see the LICENSE file for details.