bug

Crates.iobug
lib.rsbug
version0.3.1
created_at2025-09-02 02:19:48.924111+00
updated_at2025-09-03 18:18:42.282558+00
descriptionA 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
id1820429
size83,437
Tristan Poland (Trident_For_U) (tristanpoland)

documentation

README

bug

Crates.io Documentation License

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.

โœจ Features

  • ๐ŸŽฏ Template-based bug reporting - Define reusable issue templates with named parameters
  • ๐Ÿ“„ File-based templates - Load templates from markdown files using include_str! macro
  • ๐Ÿท๏ธ Label support - Automatically apply labels to GitHub issues
  • โœ… Parameter validation - Ensures all template placeholders are properly filled at compile time
  • ๐ŸŒ URL encoding - Handles special characters in URLs automatically
  • ๐Ÿ“ Multiple templates - Support for different issue types per project
  • ๐Ÿ› ๏ธ no_std support - Works in embedded and no_std environments with --no-default-features
  • ๐Ÿ“ฆ Handle-based API - Alternative API that doesn't rely on global state

๐Ÿ“ฆ Installation

Add this to your Cargo.toml:

[dependencies]
bug = "0.2.0"

no_std Support

For embedded or no_std environments:

[dependencies]
bug = { version = "0.2.0", default-features = false }

๐Ÿš€ Quick Start

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=...

๐Ÿ› ๏ธ no_std and Handle-based API

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", &params).unwrap();
}

no_std Considerations

In no_std mode:

  • Use FxHashMap instead of std::collections::HashMap
  • Global bug!() macro returns empty string (use bug_with_handle!() instead)
  • Terminal hyperlink detection is disabled (specify HyperlinkMode::Always or Never explicitly)
  • Custom output via the Output trait for logging to different targets

Custom Output in no_std

#[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", &params, file!(), line!(), &mut output);

๐Ÿ“‹ Template Files

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(())
}

๐ŸŽฏ Usage Examples

Multiple Template Types

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(())
}

Comprehensive Bug Reports

// 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");

๐Ÿ“Š Output Format

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...

๐Ÿ”— Terminal Hyperlinks & Clean URLs

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.

๐Ÿ–ฑ๏ธ Hyperlink Modes

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()?;

๐Ÿ“บ Supported Terminals

Automatic detection works with:

  • Windows Terminal
  • iTerm2 (macOS)
  • WezTerm
  • Alacritty
  • VS Code Integrated Terminal
  • Most xterm-compatible terminals

๐Ÿ“„ Output Comparison

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.

๐Ÿ“š API Reference

Core Functions

  • 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 sequence
  • supports_hyperlinks() - Detect terminal hyperlink support (std only, no_std returns false)

Structs

  • IssueTemplate - Represents a GitHub issue template
  • TemplateFile - File-based template with validation
  • BugReportConfigBuilder - Fluent API for configuration (std only)
  • BugReportHandle - Handle-based bug reporting (std and no_std)
  • HyperlinkMode - Configure hyperlink display behavior

Types

  • FxHashMap<K, V> - HashMap type used by the API (re-exported from hashbrown)
  • Output - Trait for custom output in no_std environments

Enums

  • HyperlinkMode::Auto - Auto-detect terminal support (default, std only)
  • HyperlinkMode::Always - Always use hyperlinks
  • HyperlinkMode::Never - Always show full URLs

Macros

  • template_file!(path, labels: [...]) - Load template from file
  • bug!(template, {key = value, ...}) - Report bug with parameters (std only)
  • bug_with_handle!(handle, template, {key = value, ...}) - Report bug with handle (std and no_std)

Feature Flags

  • std (default) - Enable std support with global state and environment detection
  • When std is disabled: no_std mode with handle-based API only

๐Ÿงช Examples

See the examples/ directory for complete working examples:

Run 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

๐Ÿค Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

Commit count: 0

cargo fmt