intuicio_plugins/
lib.rs

1use intuicio_core::{crate_version, registry::Registry, IntuicioVersion};
2use libloading::Library;
3use std::{cell::RefCell, collections::HashMap};
4
5thread_local! {
6    static LIBRARIES: RefCell<HashMap<String, Library>> = Default::default();
7}
8
9#[derive(Debug, Copy, Clone)]
10pub struct IncompatibleVersionsError {
11    pub host: IntuicioVersion,
12    pub plugin: IntuicioVersion,
13}
14
15impl std::fmt::Display for IncompatibleVersionsError {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        write!(
18            f,
19            "Incompatible host ({}) and plugin ({}) versions!",
20            self.host, self.plugin
21        )
22    }
23}
24
25impl std::error::Error for IncompatibleVersionsError {}
26
27pub fn install_plugin(
28    path: &str,
29    registry: &mut Registry,
30    host_version: Option<IntuicioVersion>,
31) -> Result<(), Box<dyn std::error::Error>> {
32    unsafe {
33        let host_version = host_version.unwrap_or_else(plugins_version);
34        let library = Library::new(path)?;
35        let version = library.get::<unsafe extern "C" fn() -> IntuicioVersion>(b"version\0")?;
36        let plugin_version = version();
37        if !host_version.is_compatible(&plugin_version) {
38            return Err(Box::new(IncompatibleVersionsError {
39                host: host_version,
40                plugin: plugin_version,
41            }));
42        }
43        let install = library.get::<unsafe extern "C" fn(&mut Registry)>(b"install\0")?;
44        install(registry);
45        LIBRARIES.with(|map| map.borrow_mut().insert(path.to_owned(), library));
46        Ok(())
47    }
48}
49
50pub fn plugins_version() -> IntuicioVersion {
51    crate_version!()
52}