use std::ops::{Deref, DerefMut};
#[derive(Clone)]
pub struct NonCopy<T: ?Sized>(pub T);
pub struct GuardedValue<GuardType, ValueType> {
guard: GuardType,
value: ValueType,
}
impl<GuardType, ValueType> GuardedValue<GuardType, ValueType> {
pub fn new(guard: GuardType, value: ValueType) -> Self {
Self { guard, value }
}
pub fn into(self) -> (GuardType, ValueType) { (self.guard, self.value) }
}
impl<'a, GuardType: 'a + Deref<Target = TargetType>, TargetType>
GuardedValue<GuardType, NonCopy<&'a TargetType>>
{
pub fn new_derefed(guard: GuardType) -> Self {
let derefed: *const TargetType = &*guard;
Self {
guard,
value: NonCopy(unsafe { &*derefed } as &'a TargetType),
}
}
}
impl<'a, GuardType: 'a + DerefMut<Target = TargetType>, TargetType>
GuardedValue<GuardType, &'a mut TargetType>
{
pub fn new_derefed_mut(mut guard: GuardType) -> Self {
let derefed_mut: *mut TargetType = &mut *guard;
Self {
guard,
value: unsafe { &mut *derefed_mut } as &'a mut TargetType,
}
}
}
impl<GuardType, ValueType> AsRef<ValueType>
for GuardedValue<GuardType, ValueType>
{
fn as_ref(&self) -> &ValueType { &self.value }
}
impl<GuardType, ValueType> AsMut<ValueType>
for GuardedValue<GuardType, ValueType>
{
fn as_mut(&mut self) -> &mut ValueType { &mut self.value }
}
impl<GuardType, ValueType: Deref> Deref for GuardedValue<GuardType, ValueType> {
type Target = ValueType::Target;
fn deref(&self) -> &Self::Target { self.value.deref() }
}
impl<GuardType, ValueType: DerefMut> DerefMut
for GuardedValue<GuardType, ValueType>
{
fn deref_mut(&mut self) -> &mut Self::Target { self.value.deref_mut() }
}
impl<T: ?Sized> Deref for NonCopy<T> {
type Target = T;
fn deref(&self) -> &Self::Target { &self.0 }
}
impl<T: ?Sized> DerefMut for NonCopy<T> {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}