//! A helper type for Arc> //! Currently there are mut versions (of Ref stuff) which don't do anything different under the hood, //! leaving them in for now in case I decide RwLock is a desired feature use std::{ marker::Unsize, ops::{CoerceUnsized, Deref, DerefMut}, sync::{Arc, MappedMutexGuard, Mutex, MutexGuard, Weak}, }; pub struct Handle(Arc>); pub struct WeakHandle(Weak>); pub type Ref<'a, T> = MutexGuard<'a, T>; pub type RefMut<'a, T> = MutexGuard<'a, T>; pub type RefMap<'a, T> = MappedMutexGuard<'a, T>; pub type RefMapMut<'a, T> = MappedMutexGuard<'a, T>; impl Handle { pub fn get(&self) -> Ref<'_, T> { self.0.lock().unwrap() } pub fn get_mut(&self) -> RefMut<'_, T> { self.0.lock().unwrap() } pub fn get_take<'a>(self) -> RefGuard<'a, T> { let handle = self; RefGuard { guard: unsafe { std::mem::transmute::, MutexGuard<'_, T>>( handle.0.lock().unwrap(), ) }, handle, } } pub fn get_take_mut<'a>(self) -> RefGuardMut<'a, T> { let handle = self; RefGuardMut { guard: unsafe { std::mem::transmute::, MutexGuard<'_, T>>( handle.0.lock().unwrap(), ) }, handle, } } pub fn refs(&self) -> usize { Arc::strong_count(&self.0) } pub fn weak(&self) -> WeakHandle { WeakHandle(Arc::downgrade(&self.0)) } /// # Safety /// you must guarantee the type outside /// ideally you check the typeid, but this is often used /// when the trait object is wrapped one or more times /// and you'd have to implement each one individually pub unsafe fn downcast(self) -> Handle where T: 'static, { let raw: *const Mutex = Arc::into_raw(self.0); let raw: *const Mutex = raw.cast(); Handle(unsafe { Arc::from_raw(raw) }) } } impl WeakHandle { pub fn strong(&self) -> Option> { Some(Handle(self.0.upgrade()?)) } pub fn dropped(&self) -> bool { self.0.strong_count() == 0 } /// # Safety /// you must guarantee the type outside pub unsafe fn downcast(self) -> WeakHandle where T: 'static, { let raw: *const Mutex = self.0.into_raw(); let raw: *const Mutex = raw.cast(); WeakHandle(unsafe { Weak::from_raw(raw) }) } } impl Clone for Handle { fn clone(&self) -> Self { Self(self.0.clone()) } } impl Clone for WeakHandle { fn clone(&self) -> Self { Self(self.0.clone()) } } impl Default for Handle { fn default() -> Self { Self(Default::default()) } } impl From for Handle { fn from(value: T) -> Self { Self(Arc::new(Mutex::new(value))) } } impl, U: ?Sized> CoerceUnsized> for Handle {} impl, U: ?Sized> CoerceUnsized> for WeakHandle {} // yucky // TODO: is drop order important here? // something stupid could happen that I don't know about // if handle is dropped before guard pub struct RefGuard<'a, T: ?Sized> { guard: MutexGuard<'a, T>, handle: Handle, } pub struct RefGuardMut<'a, T: ?Sized> { guard: MutexGuard<'a, T>, handle: Handle, } pub struct MappedRefGuard<'a, T: ?Sized, U> { guard: MappedMutexGuard<'a, U>, handle: Handle, } pub struct MappedRefGuardMut<'a, T: ?Sized, U> { guard: MappedMutexGuard<'a, U>, handle: Handle, } impl<'a, T: ?Sized> RefGuard<'a, T> { pub fn map(s: Self, f: impl FnOnce(&mut T) -> &mut U) -> MappedRefGuard<'a, T, U> { MappedRefGuard { guard: MutexGuard::map(s.guard, f), handle: s.handle, } } } impl<'a, T: ?Sized> RefGuardMut<'a, T> { pub fn map(s: Self, f: impl FnOnce(&mut T) -> &mut U) -> MappedRefGuardMut<'a, T, U> { MappedRefGuardMut { guard: MutexGuard::map(s.guard, f), handle: s.handle, } } } impl<'a, T: ?Sized, U> MappedRefGuard<'a, T, U> { pub fn map(s: Self, f: impl FnOnce(&mut U) -> &mut U2) -> MappedRefGuard<'a, T, U2> { MappedRefGuard { guard: MappedMutexGuard::map(s.guard, f), handle: s.handle, } } } impl<'a, T: ?Sized, U> MappedRefGuardMut<'a, T, U> { pub fn map(s: Self, f: impl FnOnce(&mut U) -> &mut U2) -> MappedRefGuardMut<'a, T, U2> { MappedRefGuardMut { guard: MappedMutexGuard::map(s.guard, f), handle: s.handle, } } } impl Deref for RefGuard<'_, T> { type Target = T; fn deref(&self) -> &Self::Target { &self.guard } } impl Deref for RefGuardMut<'_, T> { type Target = T; fn deref(&self) -> &Self::Target { &self.guard } } impl DerefMut for RefGuardMut<'_, T> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.guard } } impl Deref for MappedRefGuard<'_, T, U> { type Target = U; fn deref(&self) -> &Self::Target { &self.guard } } impl Deref for MappedRefGuardMut<'_, T, U> { type Target = U; fn deref(&self) -> &Self::Target { &self.guard } } impl DerefMut for MappedRefGuardMut<'_, T, U> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.guard } }