1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//! Hooks
use pyo3::prelude::*;
/// Dictionary-like container for Breezy hooks.
pub struct HookDict(Py<PyAny>);
/// Represents an individual hook function.
pub struct Hook(Py<PyAny>);
impl HookDict {
/// Create a new hook dictionary.
///
/// # Arguments
///
/// * `module` - The Python module containing the hook point
/// * `cls` - The class name within the module
/// * `name` - The name of the hook point
pub fn new(module: &str, cls: &str, name: &str) -> Self {
Python::attach(|py| -> PyResult<HookDict> {
let module = PyModule::import(py, module)?;
let cls = module.getattr(cls)?;
let entrypoint = cls.getattr(name)?;
Ok(Self(entrypoint.unbind()))
})
.unwrap()
}
/// Clear all hooks registered for a given name.
///
/// # Arguments
///
/// * `name` - The name of the hook point
///
/// # Returns
///
/// `Ok(())` on success, or an error if the operation fails
pub fn clear(&self, name: &str) -> Result<(), crate::error::Error> {
Python::attach(|py| {
let entrypoint = self.0.bind(py).get_item(name)?;
entrypoint.call_method0("clear")?;
Ok(())
})
}
/// Add a hook function for a given name.
///
/// # Arguments
///
/// * `name` - The name of the hook point
/// * `func` - The hook function to add
///
/// # Returns
///
/// `Ok(())` on success, or an error if the operation fails
pub fn add(&self, name: &str, func: Hook) -> Result<(), crate::error::Error> {
Python::attach(|py| {
let entrypoint = self.0.bind(py).get_item(name)?;
entrypoint.call_method1("add", (func.0,))?;
Ok(())
})
}
/// Get all hook functions registered for a given name.
///
/// # Arguments
///
/// * `name` - The name of the hook point
///
/// # Returns
///
/// A vector of hook functions, or an error if the operation fails
pub fn get(&self, name: &str) -> Result<Vec<Hook>, crate::error::Error> {
Python::attach(|py| {
let entrypoint = self.0.bind(py).get_item(name)?;
Ok(entrypoint
.extract::<Vec<Py<PyAny>>>()?
.into_iter()
.map(Hook)
.collect())
})
}
}