use std::cell::UnsafeCell;
use std::fmt;
use std::sync::{Arc, Weak};
pub struct WeakSelf<T: ?Sized> {
cell: UnsafeCell<Option<Weak<T>>>
}
impl<T: ?Sized> WeakSelf<T> {
pub fn new() -> WeakSelf<T> {
WeakSelf {
cell: UnsafeCell::new(None)
}
}
pub fn init(&self, content: &Arc<T>) {
if Arc::strong_count(content) != 1 || Arc::weak_count(content) != 0 {
panic!("Exclusive access to Arc<T> is required while initializing WeakSelf<T>");
}
let weak = Arc::downgrade(content);
unsafe {
*self.cell.get() = Some(weak);
}
}
pub fn try_get(&self) -> Option<&Weak<T>> {
unsafe {
match *self.cell.get() {
Some(ref weak) => Some(&weak),
None => None
}
}
}
pub fn get(&self) -> Weak<T> {
self.try_get().expect("expected WeakSelf to be initialized").clone()
}
}
unsafe impl<T: ?Sized + Sync + Send> Sync for WeakSelf<T> {}
unsafe impl<T: ?Sized + Sync + Send> Send for WeakSelf<T> {}
impl<T: ?Sized + fmt::Debug> fmt::Debug for WeakSelf<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.try_get() {
None => { write!(f, "Empty WeakSelf<T>") }
Some(weak) => fmt::Debug::fmt(weak, f),
}
}
}
impl<T: ?Sized> Default for WeakSelf<T> {
fn default() -> Self {
WeakSelf::new()
}
}