cilium 0.0.0

An experimental Rust library for interfacing with Microsoft's CLI assembly format.
Documentation
use std::cell::{Ref, RefCell};
use std::path::Path;
use std::pin::Pin;

use bumpalo::Bump;
use derivative::Derivative;
use fxhash::FxHashMap;

use crate::structured::assembly::{Assembly, AssemblyLoadingError, AssemblyName};
use crate::structured::resolver::{AssemblyResolver, AssemblyResolverResult, DefaultAssemblyResolver};

#[derive(Derivative)]
#[derivative(Debug)]
pub struct Context<'l> {
	#[derivative(Debug = "ignore")]
	bump: Pin<Box<Bump>>,
	#[derivative(Debug(format_with="crate::utilities::fmt_debug_values"))]
	loaded_assemblies: FxHashMap<&'l AssemblyName<'l>, &'l Assembly<'l>>,
	#[derivative(Debug = "ignore")]
	resolver: RefCell<Box<dyn AssemblyResolver>>,
}

impl<'l> Context<'l> {
	pub fn new<T: AsRef<Path>>(paths: impl IntoIterator<Item=T>) -> Self {
		Self::with_resolver(DefaultAssemblyResolver::new(paths))
	}

	pub fn with_resolver<T: AssemblyResolver + 'static>(resolver: T) -> Self {
		Context {
			bump: Pin::new(Box::new(Bump::new())),
			loaded_assemblies: Default::default(),
			resolver: RefCell::new(Box::new(resolver)),
		}
	}

	#[inline]
	pub fn loaded_assemblies(&self) -> &FxHashMap<&'l AssemblyName<'l>, &'l Assembly<'l>> {
		&self.loaded_assemblies
	}

	#[inline]
	pub fn load_assembly(&mut self, path: impl AsRef<Path>) -> Result<&'l Assembly<'l>, AssemblyLoadingError> {
		Assembly::load_from_path(self, &path)
	}

	#[inline]
	pub fn resolve_assembly_name(&self, name: &AssemblyName) -> AssemblyResolverResult<'l> {
		self.resolver.borrow_mut().resolve_assembly_name(self, name)
	}

	#[inline]
	pub fn assembly_resolver(&self) -> Ref<'_, Box<dyn AssemblyResolver>> {
		self.resolver.borrow()
	}

	#[inline]
	pub(crate) fn bump(&self) -> &'l Bump {
		unsafe { std::mem::transmute(&*self.bump) }
	}

	#[inline]
	pub(crate) fn loaded_assemblies_mut(&mut self) -> &mut FxHashMap<&'l AssemblyName<'l>, &'l Assembly<'l>> {
		&mut self.loaded_assemblies
	}
}