1use core::fmt;
2use crate::nn::ro;
3
4pub type Callback = extern "Rust" fn(&NroInfo);
5
6#[derive(Debug, Clone, Copy)]
8pub struct NroHookPluginMissing;
9
10#[allow(improper_ctypes)]
11extern "C" {
12    fn add_nro_load_hook(callback: Callback);
13    fn add_nro_unload_hook(callback: Callback);
14}
15
16pub fn add_hook(callback: Callback) -> Result<(), NroHookPluginMissing> {
20    unsafe { add_nro_load_hook(callback); }
22        Ok(())
23
24}
25
26pub fn add_unload_hook(callback: Callback) -> Result<(), NroHookPluginMissing> {
27    unsafe { add_nro_unload_hook(callback); }
28    Ok(())
29}
30
31#[repr(C)]
33#[non_exhaustive]
34pub struct NroInfo<'a> {
35    pub name: &'a str,
36    pub module: &'a mut ro::Module
37}
38
39impl<'a> NroInfo<'a> {
40    #[cfg(feature = "nro_internal")]
43    pub fn new(name: &'a str, module: &'a mut ro::Module) -> Self {
44        Self { name, module }
45    }
46}
47
48impl fmt::Display for NroHookPluginMissing {
49    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
50        write!(f, "The NRO hook plugin could not be found and is required to add NRO hooks. Make sure hook_nro.nro is installed.")
51    }
52}