Skip to main content

hyperlane/hook/
fn.rs

1use crate::*;
2
3/// Creates a default `ServerControlHook` instance with default no-op hooks.
4///
5/// The default `wait_hook` and `shutdown_hook` do nothing, allowing the server
6/// to run without specific shutdown or wait logic unless configured otherwise.
7///
8/// # Returns
9///
10/// - `ServerControlHookHandler<()>` - A default `ServerControlHookHandler<()>` instance.
11#[inline(always)]
12pub fn default_server_control_hook_handler() -> ServerControlHookHandler<()> {
13    Arc::new(|| Box::pin(async {}))
14}
15
16/// Creates a default `ServerHookHandler` from a trait object.
17///
18/// # Returns
19///
20/// - `ServerHookHandler` - A default `ServerHookHandler` instance.
21#[inline(always)]
22pub fn default_server_hook_handler() -> ServerHookHandler {
23    Arc::new(|_: &mut Stream, _: &mut Context| -> FutureBox<Status> {
24        Box::pin(async move { Status::default() })
25    })
26}
27
28/// Creates a new `ServerHookHandler` from a trait object.
29///
30/// # Arguments
31///
32/// - `ServerHook` - The trait object implementing `ServerHook`.
33///
34/// # Returns
35///
36/// - `ServerHookHandler` - A new `ServerHookHandler` instance.
37#[inline(always)]
38pub fn server_hook_factory<R>() -> ServerHookHandler
39where
40    R: ServerHook,
41{
42    Arc::new(
43        move |stream: &mut Stream, ctx: &mut Context| -> FutureBox<Status> {
44            let ctx_address: usize = ctx.into();
45            let stream_address: usize = stream.into();
46            Box::pin(async move {
47                let ctx: &mut Context = ctx_address.into();
48                let stream: &mut Stream = stream_address.into();
49                R::new(stream, ctx).await.handle(stream, ctx).await
50            })
51        },
52    )
53}
54
55/// Verifies that hooks with the same type and execution priority are unique.
56///
57/// This function validates that no two hooks of the same type have identical
58/// execution priorities (orders). Only hooks that define an explicit priority
59/// (non-None order) are checked for uniqueness. Hooks without a priority are
60/// ignored in duplicate detection.
61///
62/// # Arguments
63///
64/// - `Vec<HookType>` - A vector of `HookType` instances to validate for uniqueness.
65///
66/// # Panics
67///
68/// - Panics if duplicate hooks are detected with the same type and priority,
69///   displaying the hook type and order in the error message.
70#[inline(always)]
71pub fn assert_hook_unique_order(list: Vec<HookType>) {
72    let mut seen: HashSet<(HookType, isize)> = HashSet::new();
73    list.iter().for_each(|hook| {
74        if let Some(order) = hook.try_get_order()
75            && !seen.insert((*hook, order))
76        {
77            panic!("Duplicate hook detected: {} with order {}", hook, order);
78        }
79    });
80}