hook_macro 0.1.0

Procedural macro for generating runtime hook system with before/on/after callbacks
Documentation
  • Coverage
  • 50%
    1 out of 2 items documented0 out of 1 items with examples
  • Size
  • Source code size: 24.1 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 163.1 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 4s Average build duration of successful builds.
  • all releases: 4s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • HFunction2013/hook_macro
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • HFunction2013

hook_macro

crates.io docs.rs license rust

Procedural macro for generating runtime hook systems with before/on/after callbacks.

Features

  • 🔧 Automatically generates before, on, and after hook chains
  • 🌐 Supports FFI export for C/C++ interop
  • 🛡️ Reentrancy protection to prevent infinite loops
  • 🎨 Customizable naming with prefix, suffix, and mangling options
  • 💾 Configurable fallback return value when hooks interrupt execution

Installation

Add to your Cargo.toml:

[dependencies]
hook_macro = "0.1"

Quick Start

use hook_macro::register_hook;

#[register_hook]
fn add_one(x: i32) -> i32 {
    x + 1
}

fn main() {
    // Register hooks
    register_before_add_one(|x| {
        println!("Before: {}", x);
        false // Return true to interrupt execution
    });

    register_on_add_one(|x| {
        println!("On: {}", x);
        false
    });

    register_after_add_one(|x| {
        println!("After: {}", x);
        false
    });

    // Call the wrapped function
    let result = unsafe { add_one(5) };
    println!("Result: {}", result);
}

Examples

With Fallback

use hook_macro::register_hook;

#[register_hook(fallback = "0")]
fn divide(a: i32, b: i32) -> i32 {
    a / b
}

fn main() {
    // Interrupt the call and return fallback value
    register_before_divide(|_| true); // Always interrupt

    let result = unsafe { divide(10, 2) };
    assert_eq!(result, 0); // Returns fallback value
}

Custom Naming

use hook_macro::register_hook;

// Rename the original implementation
#[register_hook(suffix = "_original")]
fn my_function(x: i32) -> i32 {
    x * 2
}

// Or use custom prefix
#[register_hook(prefix = "impl_")]
fn another_function(x: i32) -> i32 {
    x + 1
}

// Or fully control the name
#[register_hook(mangling = "custom_impl_name")]
fn third_function(x: i32) -> i32 {
    x - 1
}

Generated API

For a function foo with one parameter, the macro generates:

Function Description
register_before_foo(hook) Register a before hook
register_on_foo(hook) Register an on hook
register_after_foo(hook) Register an after hook
clear_foo_hooks() Clear all hooks

Hook Types

With parameter T:

type BeforeFooHook = unsafe extern "C" fn(*mut T) -> bool;
type OnFooHook = unsafe extern "C" fn(*const T) -> bool;
type AfterFooHook = unsafe extern "C" fn(*const T) -> bool;

Without parameters:

type BeforeFooHook = unsafe extern "C" fn() -> bool;
type OnFooHook = unsafe extern "C" fn() -> bool;
type AfterFooHook = unsafe extern "C" fn() -> bool;

Return true from a hook to interrupt the chain and stop execution.

Attribute Parameters

Parameter Type Default Description
fallback string Default::default() Return value when hooks interrupt execution
prefix string "" Prefix for the original implementation name
suffix string "_impl" Suffix for the original implementation name
mangling string None Full custom name for the original implementation

Limitations

  • Functions can have at most one parameter
  • Parameter type must implement Clone
  • Return type must implement Default (unless fallback is specified)

License

This project is licensed under the LICENSE.