use libloading::{Library, Symbol};
use std::path::Path;
use std::fs;
use std::rc::Rc;
use auto::ffi;
pub struct Rute {
_lib: Rc<Library>,
pub ffi_api: *const ffi::RuteFFI,
}
#[cfg(target_os = "windows")]
const LIB_NAME: &str = "rute.dll";
#[cfg(target_os = "macos")]
const LIB_NAME: &str = "librute.dylib";
#[cfg(target_os = "linux")]
const LIB_NAME: &str = "librute.so";
impl Rute {
pub fn new() -> Result<Rute, String> {
let path = Path::new(env!("OUT_DIR")).join(LIB_NAME);
Self::new_from_path(path.to_str().unwrap())
}
pub fn new_from_path(path: &str) -> Result<Rute, String> {
let data = match fs::metadata(path) {
Err(e) => {
return Err(format!("Unable to find file {}: error {}", path, e));
}
Ok(data) => data,
};
if !data.is_file() {
return Err(format!("Rute: Path is not a file: {}", path));
}
let lib = match Library::new(path) {
Err(e) => return Err(format!("Found Rute sharedlib at {} but was unable to open it.
This can be because of the Qt sharedlibs/dlls not being in path.
Make sure they are and try again: error {}", path, e)),
Ok(lib) => Rc::new(lib),
};
let rute_get;
unsafe {
let t: Result<Symbol<unsafe extern "C" fn() -> *const ffi::RuteFFI>, ::std::io::Error> = lib.get(b"rute_get\0");
rute_get = match t {
Ok(func) => func,
Err(e) => {
return Err(format!("Loaded Rute sharedlib {} but was unable to find \"rute_get\" function in the lib: error {}", path, e));
}
};
}
Ok(Rute {
_lib: lib.clone(),
ffi_api: unsafe { rute_get() },
})
}
}