safe-hook 0.2.2

A safe and simple inline hook library for Rust.
Documentation
use safe_hook::Hook;
use safe_hook_macros::hookable;
use std::sync::Arc;

#[hookable("concat")]
fn concat<'a>(left: &'a str, right: &'a str) -> String {
    format!("{}-{}", left, right)
}

struct ConcatHook {
    mid: String,
}

impl Hook for ConcatHook {
    type Args<'b> = (&'b str, &'b str);
    type Result = String;

    fn call<'a>(
        &'a self,
        args: Self::Args<'a>,
        next: &dyn for<'c> Fn(Self::Args<'c>) -> Self::Result,
    ) -> Self::Result {
        let (left, right) = args;
        let lest_new = format!("{}-{}", left, self.mid);
        let res = next((&lest_new, right));
        res
    }
}

#[test]
fn test() {
    let hookable_metadata = safe_hook::lookup_hookable("concat").unwrap();
    assert_eq!(concat("abc", "def"), "abc-def");
    let hook1 = Arc::new(ConcatHook {
        mid: "hook1".to_string(),
    });
    hookable_metadata.add_hook(hook1.clone()).unwrap();
    assert_eq!(concat("abc", "def"), "abc-hook1-def");
    let hook2 = Arc::new(ConcatHook {
        mid: "hook2".to_string(),
    });
    hookable_metadata.add_hook(hook2.clone()).unwrap();
    assert_eq!(concat("abc", "def"), "abc-hook2-hook1-def");
    let x = hookable_metadata.remove_hook(hook1.as_ref());
    assert!(x);
    assert_eq!(concat("abc", "def"), "abc-hook2-def");
    let x = hookable_metadata.remove_hook(hook2.as_ref());
    assert!(x);
    assert_eq!(concat("abc", "def"), "abc-def");
    let x = hookable_metadata.remove_hook(hook2.as_ref());
    assert!(!x);
}