use std::{collections::HashMap, marker::PhantomData};
mod constant;
mod default;
mod empty;
mod indexed;
mod small;
pub use constant::ConstantResolver;
pub use default::DefaultResolver;
pub use empty::EmptyResolver;
pub use indexed::IndexedResolver;
pub use small::SmallResolver;
pub trait LockedResolver<T>: Resolver<Locked, T>
{
fn get_ptr<'a>(&'a self, name: &str) -> Option<Ptr<'a, T>>
{
self.resolve(name).map(|v| Ptr {
ptr: v as *const T as *mut T,
_marker: std::marker::PhantomData,
})
}
}
pub trait UnlockedResolver<T, R: LockedResolver<T>>: Resolver<Unlocked, T>
{
fn lock(self) -> R;
}
pub trait ResolverState {}
pub struct Locked;
pub struct Unlocked;
impl ResolverState for Locked {}
impl ResolverState for Unlocked {}
#[derive(Debug, PartialEq, Copy, Clone)]
pub struct Ptr<'a, T>
{
ptr: *mut T,
_marker: PhantomData<&'a ()>,
}
impl<'a, T> Ptr<'a, T>
where
T: Copy,
{
#[inline]
pub fn set(&self, value: T)
{
unsafe {
*self.ptr = value;
}
}
#[inline]
pub fn get(&self) -> T
{
unsafe { *self.ptr }
}
}
pub trait Resolver<State, T>
where
State: ResolverState,
{
fn resolve(&self, name: &str) -> Option<&T>;
}
impl<T> Resolver<Unlocked, T> for HashMap<String, T>
{
fn resolve(&self, name: &str) -> Option<&T>
{
self.get(name)
}
}