#[cfg(libloading_docs)]
use super::os::unix as imp; #[cfg(all(not(libloading_docs), unix))]
use super::os::unix as imp;
#[cfg(all(not(libloading_docs), windows))]
use super::os::windows as imp;
use super::Error;
use crate::as_filename::AsFilename;
use crate::as_symbol_name::AsSymbolName;
use core::fmt;
use core::marker;
use core::ops;
#[cfg_attr(libloading_docs, doc(cfg(any(unix, windows))))]
pub struct Library(imp::Library);
impl Library {
pub unsafe fn new(filename: impl AsFilename) -> Result<Library, Error> {
imp::Library::new(filename).map(From::from)
}
pub unsafe fn get<T>(&self, symbol: impl AsSymbolName) -> Result<Symbol<'_, T>, Error> {
self.0.get(symbol).map(|from| Symbol::from_raw(from, self))
}
pub fn close(self) -> Result<(), Error> {
self.0.close()
}
}
impl fmt::Debug for Library {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl From<imp::Library> for Library {
fn from(lib: imp::Library) -> Library {
Library(lib)
}
}
impl From<Library> for imp::Library {
fn from(lib: Library) -> imp::Library {
lib.0
}
}
unsafe impl Send for Library {}
unsafe impl Sync for Library {}
#[cfg_attr(libloading_docs, doc(cfg(any(unix, windows))))]
pub struct Symbol<'lib, T: 'lib> {
inner: imp::Symbol<T>,
pd: marker::PhantomData<&'lib T>,
}
impl<'lib, T> Symbol<'lib, T> {
pub unsafe fn into_raw(self) -> imp::Symbol<T> {
self.inner
}
pub unsafe fn from_raw<L>(sym: imp::Symbol<T>, library: &'lib L) -> Symbol<'lib, T> {
let _ = library; Symbol {
inner: sym,
pd: marker::PhantomData,
}
}
pub unsafe fn try_as_raw_ptr(self) -> Option<*mut core::ffi::c_void> {
Some(
unsafe {
self.into_raw()
}
.as_raw_ptr(),
)
}
}
impl<'lib, T> Symbol<'lib, Option<T>> {
pub fn lift_option(self) -> Option<Symbol<'lib, T>> {
self.inner.lift_option().map(|is| Symbol {
inner: is,
pd: marker::PhantomData,
})
}
}
impl<'lib, T> Clone for Symbol<'lib, T> {
fn clone(&self) -> Symbol<'lib, T> {
Symbol {
inner: self.inner.clone(),
pd: marker::PhantomData,
}
}
}
impl<T> ops::Deref for Symbol<'_, T> {
type Target = T;
fn deref(&self) -> &T {
ops::Deref::deref(&self.inner)
}
}
impl<T> fmt::Debug for Symbol<'_, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
unsafe impl<T: Send> Send for Symbol<'_, T> {}
unsafe impl<T: Sync> Sync for Symbol<'_, T> {}