use crate::raw;
use super::super::Error;
use super::super::raw::Library;
use super::api::WrapperApi;
use std::ffi::OsStr;
use std::ops::{Deref, DerefMut};
pub struct Container<T>
where
T: WrapperApi,
{
#[allow(dead_code)]
lib: Library,
api: T,
}
impl<T> Container<T>
where
T: WrapperApi,
{
pub unsafe fn load<S>(name: S) -> Result<Container<T>, Error>
where
S: AsRef<OsStr>,
{
unsafe {
let lib = Library::open(name)?;
let api = T::load(&lib)?;
Ok(Self { lib, api })
}
}
pub unsafe fn load_self() -> Result<Container<T>, Error> {
unsafe {
let lib = Library::open_self()?;
let api = T::load(&lib)?;
Ok(Self { lib, api })
}
}
pub unsafe fn into_raw(&self) -> raw::Handle {
unsafe { self.lib.into_raw() }
}
pub unsafe fn load_with_flags<S>(name: S, flags: Option<i32>) -> Result<Container<T>, Error>
where
S: AsRef<OsStr>,
{
unsafe {
let lib = Library::open_with_flags(name, flags)?;
let api = T::load(&lib)?;
Ok(Self { lib, api })
}
}
}
impl<T> Deref for Container<T>
where
T: WrapperApi,
{
type Target = T;
fn deref(&self) -> &T {
&self.api
}
}
impl<T> DerefMut for Container<T>
where
T: WrapperApi,
{
fn deref_mut(&mut self) -> &mut T {
&mut self.api
}
}