pub mod api_traits;
pub mod error;
pub mod headers;
pub mod key_types;
use abi_stable::type_layout::TypeLayout;
use abi_stable::StableAbi;
use api_traits::{ControllerFeatures, Loadable};
use cglue::prelude::v1::{trait_group::compare_layouts, *};
use core::mem::MaybeUninit;
use ::std::ffi::CString;
use error::{InputFlowError, Result};
use headers::PluginHeader;
use libloading::{library_filename, Library, Symbol};
#[cglue_trait]
pub trait PluginInner<'a> {
#[wrap_with_group(ControllerFeatures)]
type BorrowedType: Loadable + 'a;
#[wrap_with_group(ControllerFeatures)]
type OwnedType: Loadable + 'static;
#[wrap_with_group_mut(ControllerFeatures)]
type OwnedTypeMut: Loadable + 'a;
fn borrow_features(&'a mut self) -> Self::BorrowedType;
fn into_features(self) -> Self::OwnedType;
fn mut_features(&'a mut self) -> &'a mut Self::OwnedTypeMut;
}
pub trait Plugin: for<'a> PluginInner<'a> {}
impl<T: for<'a> PluginInner<'a>> Plugin for T {}
#[no_mangle]
pub unsafe extern "C" fn load_plugin(
name: ReprCStr<'_>,
args: ReprCStr<'_>,
ok_out: &mut MaybeUninit<PluginInnerArcBox<'static>>,
) -> i32 {
load_plugin_impl(name.as_ref(), args.as_ref()).into_int_out_result(ok_out)
}
unsafe fn load_plugin_impl(name: &str, args: &str) -> Result<PluginInnerArcBox<'static>> {
let mut current_exe = std::env::current_exe().map_err(|_| InputFlowError::Path)?;
current_exe.set_file_name(library_filename(name));
let lib = Library::new(current_exe).map_err(|e| {
println!("{}", e);
InputFlowError::Loading
})?;
let header: Symbol<&'static PluginHeader> = lib.get(b"IF_PLUGIN_HEAD\0").map_err(|e| {
println!("{}", e);
InputFlowError::Symbol
})?;
let header = header.into_raw();
if !compare_layouts(Some(ROOT_LAYOUT), Some(header.layout)).is_valid_strict() {
return Err(InputFlowError::Abi);
}
let arc = CArc::from(lib);
(header.create)(&arc.into_opaque(), CString::new(args).unwrap().into_raw())
}
#[no_mangle]
pub static ROOT_LAYOUT: &TypeLayout = PluginInnerArcBox::LAYOUT;
#[doc(hidden)]
pub mod cglue {
pub use ::cglue::prelude::v1::*;
}
#[doc(hidden)]
pub mod abi_stable {
pub use abi_stable::*;
}
#[doc(hidden)]
#[allow(ambiguous_glob_reexports)]
pub mod prelude {
pub mod v1 {
pub use crate::abi_stable;
pub use crate::api_traits::*;
pub use crate::cglue::*;
pub use crate::error::*;
pub use crate::headers::*;
pub use crate::iter::*;
pub use crate::key_types::*;
pub use crate::*;
}
pub use v1::*;
}