quantum-pulse-macros 0.1.10

Procedural macros for the quantum-pulse profiling library
Documentation

quantum-pulse-macros

Procedural macros for the quantum-pulse profiling library.

Overview

This crate provides derive macros to automatically implement profiling traits from the quantum-pulse library, reducing boilerplate code and making it easier to integrate profiling into your applications.

Features

  • #[derive(Operation)] - Automatically implements the Operation trait for enums
  • Zero-cost abstractions - Generated code is optimized away when profiling is disabled
  • Flexible categorization - Define custom categories with descriptions
  • Type-safe - All category definitions are checked at compile time

Installation

This crate is typically used as a dependency of quantum-pulse. Add to your Cargo.toml:

[dependencies]
quantum-pulse = { version = "0.1", features = ["macros"] }

Usage

Basic Example

use quantum_pulse::{ProfileOp, Operation, profile};

#[derive(Debug, ProfileOp)]
enum MyOperation {
    // Category with both name and description
    #[category(name = "IO", description = "Input/Output operations")]
    ReadFile,
    
    // Same category, description is reused
    #[category(name = "IO")]
    WriteFile,
    
    // Category with only name (description defaults to name)
    #[category(name = "Network")]
    HttpRequest,
    
    // No category attribute (uses variant name as category)
    ComputeHash,
}

fn main() {
    let op = MyOperation::ReadFile;
    let result = profile!(op, {
        // Your code here
        "file content"
    });
}

Category Attributes

The #[category(...)] attribute supports the following parameters:

  • name - The name of the category (optional, defaults to variant name)
  • description - A description of the category (optional, defaults to category name)

Important Behavior

When multiple enum variants use the same category name:

  1. Only one category struct is generated per unique category name
  2. The first description wins - The first description encountered for a category name is used
  3. Subsequent descriptions are ignored - If a category already has a description, later ones are ignored
  4. Description upgrade - If the first variant with a category name has no description (defaulting to the name), and a later variant provides one, the description is updated

Example with Shared Categories

#[derive(Debug, ProfileOp)]
enum DatabaseOps {
    #[category(name = "Query", description = "Database read operations")]
    SelectUsers,
    
    #[category(name = "Query")]  // Reuses "Database read operations" description
    SelectPosts,
    
    #[category(name = "Mutation", description = "Database write operations")]
    InsertUser,
    
    #[category(name = "Mutation")]  // Reuses "Database write operations" description
    UpdateUser,
}

Enum Variants with Data

The macro supports all enum variant types:

#[derive(Debug, ProfileOp)]
enum ComplexOperation {
    // Unit variant
    #[category(name = "Simple")]
    Basic,
    
    // Tuple variant
    #[category(name = "Database")]
    Query(String),
    
    // Struct variant
    #[category(name = "Cache")]
    CacheOp { key: String, ttl: u64 },
}

Special Characters in Category Names

Category names can contain special characters, which are automatically sanitized for internal use:

#[derive(Debug, ProfileOp)]
enum SpecialOps {
    #[category(name = "I/O Operations")]
    FileAccess,
    
    #[category(name = "CPU-Intensive")]
    HeavyCompute,
    
    #[category(name = "Memory & Cache")]
    MemoryOp,
}

How It Works

The #[derive(Operation)] macro:

  1. Parses the enum and its #[category] attributes
  2. Collects unique categories and their descriptions
  3. Generates a hidden struct for each unique category that implements the Category trait
  4. Implements the Operation trait for the enum with a get_category() method that returns the appropriate category

Generated structs are prefixed with the enum name to avoid naming conflicts when multiple enums use the same category names.

Performance

The generated code has minimal runtime overhead:

  • Category structs are zero-sized types (ZSTs)
  • The get_category() method is a simple match expression
  • All generated code can be inlined by the compiler
  • When profiling is disabled (default), everything compiles to nothing

License

This crate is part of the quantum-pulse project and is dual-licensed under MIT OR Apache-2.0.