quantum-pulse-macros 0.1.10

Procedural macros for the quantum-pulse profiling library
Documentation
# quantum-pulse-macros

Procedural macros for the [quantum-pulse](https://github.com/aovestdipaperino/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`:

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

## Usage

### Basic Example

```rust
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

```rust
#[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:

```rust
#[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:

```rust
#[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.