use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::sync::{Arc, RwLock, Weak};
pub struct AtomicRefBox<T> {
inner: Arc<Inner<T>>,
}
impl<T> AtomicRefBox<T> {
pub fn new(value: T) -> AtomicRefBox<T> {
AtomicRefBox {
inner: Arc::new(Inner {
lock: RwLock::new(Some(value)),
}),
}
}
pub fn borrow(this: &Self) -> AtomicRef<T> {
todo!()
}
pub fn borrow_mut(this: &Self) -> AtomicMutRef<T> {
todo!()
}
pub fn to_weak(this: &Self) -> AtomicWeakRef<T> {
AtomicWeakRef::new(Arc::downgrade(&this.inner))
}
pub fn into_inner(this: Self) -> T {
this.inner.lock.write().unwrap().take().unwrap()
}
}
impl<T> Deref for AtomicRefBox<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
todo!()
}
}
impl<T> AsRef<T> for AtomicRefBox<T> {
fn as_ref(&self) -> &T {
&**self
}
}
struct Inner<T> {
lock: RwLock<Option<T>>,
}
pub struct AtomicRef<'a, T> {
marker: PhantomData<&'a mut T>, }
impl<'a, T> Deref for AtomicRef<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
todo!()
}
}
pub struct AtomicMutRef<'a, T> {
marker: PhantomData<&'a mut T>, }
impl<'a, T> Deref for AtomicMutRef<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
todo!()
}
}
impl<'a, T> DerefMut for AtomicMutRef<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
todo!()
}
}
pub struct AtomicWeakRef<T> {
weak: Weak<Inner<T>>,
}
impl<T> AtomicWeakRef<T> {
fn new(weak: Weak<Inner<T>>) -> AtomicWeakRef<T> {
AtomicWeakRef { weak }
}
pub fn borrow<R>(&self, op: impl FnOnce(&T) -> R) -> Option<R> {
let Some(w) = self.weak.upgrade() else {
return None;
};
let read_binding = w.lock.read().unwrap();
let Some(t) = read_binding.deref() else {
return None;
};
Some(op(t))
}
}