Skip to main content

cpex_core/hooks/
macros.rs

1// Location: ./crates/cpex-core/src/hooks/macros.rs
2// Copyright 2025
3// SPDX-License-Identifier: Apache-2.0
4// Authors: Teryl Taylor
5//
6// define_hook! macro.
7//
8// Generates a HookTypeDef marker struct and trait implementation
9// from a single declaration. This is the primary way to define new
10// hooks — both built-in (CMF, tool, prompt) and custom (rate
11// limiting, deployment gates, federation sync).
12//
13// Plugins implement the generic HookHandler<H> trait (from
14// trait_def.rs) for the generated marker struct. The handler
15// receives a borrowed payload and returns the hook's result type.
16
17/// Generates a hook type definition and marker struct.
18///
19/// # Usage
20///
21/// ```rust,ignore
22/// define_hook! {
23///     /// Doc comment for the hook.
24///     MyHook, "my_hook" => {
25///         payload: MyPayload,
26///         result: PluginResult<MyPayload>,
27///     }
28/// }
29/// ```
30///
31/// This generates a marker struct `MyHook` implementing `HookTypeDef`.
32/// Plugins handle it by implementing `HookHandler<MyHook>`.
33///
34/// # CMF Pattern (one handler, multiple hook names)
35///
36/// For CMF hooks where one handler covers multiple hook names:
37///
38/// ```rust,ignore
39/// define_hook! {
40///     /// CMF message evaluation hook.
41///     CmfHook, "cmf" => {
42///         payload: MessagePayload,
43///         result: PluginResult<MessagePayload>,
44///     }
45/// }
46///
47/// // Register the same handler for multiple names:
48/// // manager.register_handler_for_names::<CmfHook, _>(plugin, config, &[
49/// //     "cmf.tool_pre_invoke", "cmf.llm_input", ...
50/// // ]);
51/// ```
52#[macro_export]
53macro_rules! define_hook {
54    (
55        $(#[$meta:meta])*
56        $name:ident, $hook_name:literal => {
57            payload: $payload:ty,
58            result: $result:ty $(,)?
59        }
60    ) => {
61        $(#[$meta])*
62        pub struct $name;
63
64        impl $crate::hooks::trait_def::HookTypeDef for $name {
65            type Payload = $payload;
66            type Result = $result;
67            const NAME: &'static str = $hook_name;
68        }
69    };
70}