use std::mem::MaybeUninit;
use std::path::PathBuf;
use crate::cglue::result::into_int_out_result;
use crate::error::Error;
use super::{
plugin_analyzer::{PluginArchitecture, PluginFileType},
LibArc, PluginLogger,
};
use super::{ErrorKind, ErrorOrigin};
pub fn plugin_extension() -> &'static str {
#[cfg(target_os = "windows")]
return "dll";
#[cfg(target_os = "linux")]
return "so";
#[cfg(target_os = "macos")]
return "dylib";
}
pub fn plugin_file_type() -> PluginFileType {
#[cfg(target_os = "windows")]
return PluginFileType::Pe;
#[cfg(target_os = "linux")]
return PluginFileType::Elf;
#[cfg(target_os = "macos")]
return PluginFileType::Mach;
}
pub fn plugin_architecture() -> PluginArchitecture {
#[cfg(target_arch = "x86_64")]
return PluginArchitecture::X86_64;
#[cfg(target_arch = "x86")]
return PluginArchitecture::X86;
#[cfg(target_arch = "aarch64")]
return PluginArchitecture::Arm64;
#[cfg(target_arch = "arm")]
return PluginArchitecture::Arm;
}
pub fn plugins_path() -> crate::error::Result<PathBuf> {
let path = if cfg!(unix) {
dirs::home_dir()
.unwrap()
.join(".local")
.join("lib")
.join("memflow")
} else {
dirs::document_dir().unwrap().join("memflow")
};
if !path.exists() {
std::fs::create_dir_all(&path).map_err(|_| {
Error(ErrorOrigin::Inventory, ErrorKind::UnableToCreateDirectory)
.log_error("unable to create plugins directory")
})?;
}
Ok(path)
}
pub fn wrap<A: Default, T>(
args: Option<&A>,
lib: LibArc,
logger: Option<&'static PluginLogger>,
out: &mut MaybeUninit<T>,
create_fn: impl FnOnce(&A, LibArc) -> Result<T, Error>,
) -> i32 {
if let Some(logger) = logger {
logger.init().ok();
}
let default: A = Default::default();
let args = args.unwrap_or(&default);
into_int_out_result(create_fn(args, lib), out)
}
pub fn wrap_with_input<A: Default, T, I>(
args: Option<&A>,
input: I,
lib: LibArc,
logger: Option<&'static PluginLogger>,
out: &mut MaybeUninit<T>,
create_fn: impl FnOnce(&A, I, LibArc) -> Result<T, Error>,
) -> i32 {
if let Some(logger) = logger {
logger.init().ok();
}
let default: A = Default::default();
let args = args.unwrap_or(&default);
into_int_out_result(
create_fn(args, input, lib).inspect_err(|e| {
::log::error!("{}", e);
}),
out,
)
}