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