use libloading::{Library, Symbol};
use std::os::raw::{c_char, c_double};
pub struct BrukerTimsDataLibrary {
pub lib: Library,
pub handle: u64,
}
impl BrukerTimsDataLibrary {
pub fn new(
bruker_lib_path: &str,
data_path: &str,
) -> Result<BrukerTimsDataLibrary, Box<dyn std::error::Error>> {
let lib = unsafe { Library::new(bruker_lib_path)? };
let handle = unsafe {
let func: Symbol<unsafe extern "C" fn(*const c_char, u32) -> u64> =
lib.get(b"tims_open")?;
let path = std::ffi::CString::new(data_path)?;
let handle = func(path.as_ptr(), 0);
handle
};
Ok(BrukerTimsDataLibrary { lib, handle })
}
pub fn tims_close(&self) -> Result<(), Box<dyn std::error::Error>> {
unsafe {
let func: Symbol<unsafe extern "C" fn(u64) -> ()> = self.lib.get(b"tims_close")?;
func(self.handle);
}
Ok(())
}
pub fn tims_index_to_mz(
&self,
frame_id: u32,
dbl_tofs: &[c_double],
mzs: &mut [c_double],
) -> Result<(), Box<dyn std::error::Error>> {
unsafe {
let func: Symbol<unsafe extern "C" fn(u64, u32, *const c_double, *mut c_double, u32)> =
self.lib.get(b"tims_index_to_mz")?;
func(
self.handle,
frame_id,
dbl_tofs.as_ptr(),
mzs.as_mut_ptr(),
dbl_tofs.len() as u32,
);
}
Ok(())
}
pub fn tims_mz_to_index(
&self,
frame_id: u32,
mzs: &[c_double],
indices: &mut [c_double],
) -> Result<(), Box<dyn std::error::Error>> {
unsafe {
let func: Symbol<unsafe extern "C" fn(u64, u32, *const c_double, *mut c_double, u32)> =
self.lib.get(b"tims_mz_to_index")?;
func(
self.handle,
frame_id,
mzs.as_ptr(),
indices.as_mut_ptr(),
mzs.len() as u32,
);
}
Ok(())
}
pub fn tims_scan_to_inv_mob(
&self,
frame_id: u32,
dbl_scans: &[c_double],
inv_mob: &mut [c_double],
) -> Result<(), Box<dyn std::error::Error>> {
unsafe {
let func: Symbol<unsafe extern "C" fn(u64, u32, *const c_double, *mut c_double, u32)> =
self.lib.get(b"tims_scannum_to_oneoverk0")?;
func(
self.handle,
frame_id,
dbl_scans.as_ptr(),
inv_mob.as_mut_ptr(),
dbl_scans.len() as u32,
);
}
Ok(())
}
pub fn inv_mob_to_tims_scan(
&self,
frame_id: u32,
inv_mob: &[c_double],
scans: &mut [c_double],
) -> Result<(), Box<dyn std::error::Error>> {
unsafe {
let func: Symbol<unsafe extern "C" fn(u64, u32, *const c_double, *mut c_double, u32)> =
self.lib.get(b"tims_oneoverk0_to_scannum")?;
func(
self.handle,
frame_id,
inv_mob.as_ptr(),
scans.as_mut_ptr(),
inv_mob.len() as u32,
);
}
Ok(())
}
}
impl Drop for BrukerTimsDataLibrary {
fn drop(&mut self) {
let close = self.tims_close();
match close {
Ok(_) => (),
Err(e) => println!("error: {}", e),
};
}
}