use std::
{
cell::RefCell, fmt, ops::{Deref, DerefMut}, rc::{Rc, Weak}
};
use crate::{ICoWLockTypes, ICowType};
#[derive(Debug)]
pub struct ICoWRead<'read, ITEM: Sized>
{
pub(crate) item: Rc<ITEM>,
bind: &'read ICoW<ITEM>
}
impl<'read, ITEM: Sized> Deref for ICoWRead<'read, ITEM>
{
type Target = ITEM;
fn deref(&self) -> &Self::Target
{
return &self.item;
}
}
impl<'read, ITEM: Sized> ICoWRead<'read, ITEM>
{
pub
fn into_inner(self) -> Rc<ITEM>
{
return self.item;
}
pub
fn weak(&self) -> Weak<ITEM>
{
return Rc::downgrade(&self.item);
}
}
impl<'read, ITEM: Sized + fmt::Debug + Copy> ICoWRead<'read, ITEM>
{
pub
fn upgrade_copy(self) -> ICoWCopy<'read, ITEM>
{
let new_item = *self.item;
let bind = self.bind;
return
ICoWCopy
{
prev_item: self,
new_item: new_item,
inst: bind
};
}
}
impl<'read, ITEM: Sized + fmt::Debug + Clone> ICoWRead<'read, ITEM>
{
pub
fn upgrade_clone_copy(self) -> ICoWCopy<'read, ITEM>
{
let new_item = self.item.as_ref().clone();
let bind = self.bind;
return
ICoWCopy
{
prev_item: self,
new_item: new_item,
inst: bind
};
}
}
impl<'read, ITEM: Sized + fmt::Debug + Default> ICoWRead<'read, ITEM>
{
pub
fn upgrade_default(self) -> ICoWCopy<'read, ITEM>
{
let new_item = ITEM::default();
let bind = self.bind;
return
ICoWCopy
{
prev_item: self,
new_item: new_item,
inst: bind
};
}
}
#[derive(Debug)]
pub struct ICoWCopy<'copy, ITEM: Sized>
{
prev_item: ICoWRead<'copy, ITEM>,
new_item: ITEM,
inst: &'copy ICoW<ITEM>
}
impl<'copy, ITEM: Sized> Deref for ICoWCopy<'copy, ITEM>
{
type Target = ITEM;
fn deref(&self) -> &Self::Target
{
return &self.new_item;
}
}
impl<'copy, ITEM: Sized> DerefMut for ICoWCopy<'copy, ITEM>
{
fn deref_mut(&mut self) -> &mut Self::Target
{
return &mut self.new_item
}
}
impl<'copy, ITEM: Sized> ICoWCopy<'copy, ITEM>
{
pub
fn prev_val(&self) -> &ITEM
{
return &self.prev_item;
}
pub
fn commit(self)
{
*self.inst.inner.borrow_mut() = Rc::new(self.new_item);
return;
}
pub
fn into_inner(self) -> ITEM
{
return self.new_item;
}
}
#[derive(Debug)]
pub struct ICoW<ITEM: Sized>
{
inner: RefCell<Rc<ITEM>>,
}
impl<ITEM> ICowType for ICoW<ITEM>
{
fn get_lock_type() -> ICoWLockTypes
{
return ICoWLockTypes::RwLock;
}
}
impl<ITEM> ICoW<ITEM>
{
pub
fn new(item: ITEM) -> Self
{
return
Self
{
inner:
RefCell::new(Rc::new(item)),
}
}
pub
fn read(&self) -> ICoWRead<'_, ITEM>
{
let lock =
self
.inner
.borrow();
return ICoWRead{ item: lock.clone(), bind: self };
}
pub
fn new_inplace(&self, new_item: ITEM)
{
let read = self.read();
let ret =
ICoWCopy
{
prev_item: read,
new_item: new_item,
inst: self
};
ret.commit();
return;
}
}
impl<ITEM: fmt::Debug + Copy> ICoW<ITEM>
{
pub
fn copy(&self) -> ICoWCopy<'_, ITEM>
{
let read = self.read();
let new_item = *read.item.as_ref();
let ret =
ICoWCopy
{
prev_item: read,
new_item: new_item,
inst: self
};
return ret;
}
}
impl<ITEM: fmt::Debug + Clone> ICoW<ITEM>
{
pub
fn clone_copy(&self) -> ICoWCopy<'_, ITEM>
{
let read = self.read();
let new_item = read.item.as_ref().clone();
let ret =
ICoWCopy
{
prev_item: read,
new_item: new_item,
inst: self
};
return ret;
}
}
impl<ITEM: fmt::Debug + Default> ICoW<ITEM>
{
pub
fn from_default(&self) -> ICoWCopy<'_, ITEM>
{
let read = self.read();
let new_item = ITEM::default();
let ret =
ICoWCopy
{
prev_item: read,
new_item: new_item,
inst: self
};
return ret;
}
}
#[cfg(test)]
mod test
{
}