use crate::module::library::types::{OsLibrary, VirtualLibrary};
use crate::module::library::Library;
use crate::module::loader::ModuleLoader;
use crate::module::Module;
use crate::module::Result;
use std::path::Path;
use std::sync::MutexGuard;
pub trait ModuleHandle {
type Library: Library;
fn get(&self) -> &Module<Self::Library>;
}
struct VirtualLibraryHandle<'a> {
loader: &'a ModuleLoader,
id: usize,
}
impl<'a> VirtualLibraryHandle<'a> {
fn new(loader: &'a ModuleLoader, id: usize) -> VirtualLibraryHandle<'a> {
VirtualLibraryHandle { loader, id }
}
}
impl<'a> ModuleHandle for VirtualLibraryHandle<'a> {
type Library = VirtualLibrary;
fn get(&self) -> &Module<VirtualLibrary> {
self.loader.builtin_modules.get(&self.id).unwrap()
}
}
struct OsLibraryHandle<'a> {
loader: &'a ModuleLoader,
id: usize,
}
impl<'a> OsLibraryHandle<'a> {
fn new(loader: &'a ModuleLoader, id: usize) -> OsLibraryHandle<'a> {
OsLibraryHandle { loader, id }
}
}
impl<'a> ModuleHandle for OsLibraryHandle<'a> {
type Library = OsLibrary;
fn get(&self) -> &Module<OsLibrary> {
self.loader.modules.get(&self.id).unwrap()
}
}
pub struct Lock<'a> {
pub(super) lock: MutexGuard<'a, ModuleLoader>,
}
impl<'a> Lock<'a> {
pub unsafe fn load_builtin(&mut self, name: &str) -> Result<impl ModuleHandle + '_> {
self.lock
._load_builtin(name)
.map(|id| VirtualLibraryHandle::new(&self.lock, id))
}
pub unsafe fn load_self(&mut self, name: &str) -> Result<impl ModuleHandle + '_> {
self.lock
._load_self(name)
.map(|id| OsLibraryHandle::new(&self.lock, id))
}
pub unsafe fn load(&mut self, name: &str) -> Result<impl ModuleHandle + '_> {
self.lock
._load(name)
.map(|id| OsLibraryHandle::new(&self.lock, id))
}
pub fn unload(&mut self, name: &str) -> Result<()> {
self.lock._unload(name)
}
pub fn add_search_path(&mut self, path: impl AsRef<Path>) {
self.lock._add_search_path(path);
}
pub fn remove_search_path(&mut self, path: impl AsRef<Path>) {
self.lock._remove_search_path(path);
}
pub fn add_public_dependency<'b>(
&mut self,
name: &str,
version: &str,
features: impl IntoIterator<Item = &'b str>,
) {
self.lock._add_public_dependency(name, version, features);
}
pub fn get_builtin(&self, name: &str) -> Option<impl ModuleHandle + '_> {
self.lock
._get_builtin(name)
.map(|id| VirtualLibraryHandle::new(&self.lock, id))
}
pub fn get_module(&self, name: &str) -> Option<impl ModuleHandle + '_> {
self.lock
._get_module(name)
.map(|id| OsLibraryHandle::new(&self.lock, id))
}
}