use std::{ ops::Deref, sync::{Arc, Weak}, }; use anyhow::{anyhow, Result}; pub struct StrongHandle { strong: Arc, } impl StrongHandle { pub fn new(t: T) -> Self { Self { strong: Arc::new(t), } } } impl Deref for StrongHandle { type Target = T; fn deref(&self) -> &Self::Target { &self.strong } } #[derive(Debug)] pub struct WeakHandle { weak: Weak, } impl WeakHandle { pub fn on(&self, f: F) -> Result where F: FnOnce(&T) -> Result, { let strong: Arc = self .weak .upgrade() .ok_or(anyhow!("failed to get strong handle"))?; f(&strong) } pub fn upgrade(&self) -> StrongHandle { StrongHandle { strong: self.weak.upgrade().unwrap(), } } pub fn try_upgrade(&self) -> Result> { Ok(StrongHandle { strong: self .weak .upgrade() .ok_or(anyhow!("failed to upgrade WeakHandle"))?, }) } } impl Clone for WeakHandle { fn clone(&self) -> Self { Self { weak: self.weak.clone(), } } } impl From<&StrongHandle> for WeakHandle { fn from(handle: &StrongHandle) -> Self { Self { weak: Arc::downgrade(&handle.strong), } } }