use alloc::rc::Weak;
use core::fmt;
pub struct WeakHandle<'pool, T> {
inner: Weak<super::shared::SharedHandleInner<'pool, T>>,
}
impl<'pool, T> WeakHandle<'pool, T> {
#[inline]
pub(crate) fn new(inner: Weak<super::shared::SharedHandleInner<'pool, T>>) -> Self {
Self { inner }
}
#[inline]
pub fn upgrade(&self) -> Option<super::SharedHandle<'pool, T>> {
self.inner
.upgrade()
.map(|inner| super::SharedHandle { inner })
}
#[inline]
pub fn strong_count(&self) -> usize {
self.inner.strong_count()
}
#[inline]
pub fn weak_count(&self) -> usize {
self.inner.weak_count()
}
}
impl<'pool, T> Clone for WeakHandle<'pool, T> {
fn clone(&self) -> Self {
Self {
inner: Weak::clone(&self.inner),
}
}
}
impl<'pool, T> fmt::Debug for WeakHandle<'pool, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("WeakHandle")
.field("strong_count", &self.strong_count())
.field("weak_count", &self.weak_count())
.finish()
}
}
#[cfg(test)]
mod tests {
use crate::handle::SharedHandle;
use crate::pool::FixedPool;
#[test]
fn weak_handle_upgrade() {
let pool = FixedPool::<i32>::new(10).unwrap();
let handle = pool.allocate(42).unwrap();
let index = handle.index();
let shared = SharedHandle::new(&pool, index);
let weak = shared.downgrade();
assert_eq!(weak.strong_count(), 1);
let upgraded = weak.upgrade();
assert!(upgraded.is_some());
assert_eq!(weak.strong_count(), 2);
drop(shared);
drop(upgraded);
let upgraded = weak.upgrade();
assert!(upgraded.is_none());
core::mem::forget(handle);
}
#[test]
fn weak_handle_clone() {
let pool = FixedPool::<i32>::new(10).unwrap();
let handle = pool.allocate(42).unwrap();
let index = handle.index();
let shared = SharedHandle::new(&pool, index);
let weak = shared.downgrade();
let weak2 = weak.clone();
assert_eq!(weak.weak_count(), weak2.weak_count());
drop(shared);
core::mem::forget(handle);
}
}