use std::{
ffi::CStr,
io,
sync,
};
use crate::{
Library,
Symbol,
};
#[derive(Debug)]
pub struct LibLock<'a> {
libs: &'a [&'a str],
hlib: sync::OnceLock<Library>,
}
impl<'a> LibLock<'a> {
#[inline]
pub const fn new(libs: &'a [&'a str]) -> Self {
Self {
libs,
hlib: sync::OnceLock::new(),
}
}
pub fn symbol(&self, name: &str) -> io::Result<*const Symbol> {
let lib = self.hlib.get_or_init(|| {
if self.libs.is_empty() {
Library::this()
} else {
self.libs
.iter()
.find_map(|path| Library::open(path).ok())
.unwrap()
}
});
lib.symbol(name)
}
pub fn raw_symbol(&self, name: &CStr) -> *const Symbol {
let lib = self.hlib.get_or_init(|| {
if self.libs.is_empty() {
Library::this()
} else {
self.libs
.iter()
.find_map(|path| Library::open(path).ok())
.unwrap()
}
});
lib.raw_symbol(name)
}
#[cfg(feature = "unstable")]
#[inline]
pub fn get(&self) -> Option<&Library> {
self.hlib.get()
}
#[inline]
pub fn take(&mut self) -> Option<Library> {
self.hlib.take()
}
#[cfg(feature = "unstable")]
#[inline]
pub fn set(&self, value: Library) -> Result<(), Library> {
self.hlib.set(value)
}
#[cfg(feature = "unstable")]
#[inline]
pub fn into_inner(self) -> Option<Library> {
self.hlib.into_inner()
}
}