use std::cell::RefCell;
pub struct Movable<T>(RefCell<Vec<T>>);
impl<T> Movable<T>
{
pub fn new(content: T) -> Self
{
Self(RefCell::new(vec![content]))
}
pub fn consume(&self) -> T
{
if self.has_moved()
{
panic!("Movable already consumed!")
}
else
{
self.0.borrow_mut().pop().unwrap()
}
}
pub fn has_moved(&self) -> bool
{
self.0.borrow().len() == 0
}
pub fn use_to<U, F>(&self, f: F) -> U
where
F: Fn(&T) -> U
{
if self.has_moved()
{
panic!("Movable already consumed!")
}
else
{
f(self.0.borrow()
.get(0).unwrap())
}
}
pub fn insert(&self, new: T)
{
if self.has_moved()
{
self.0.borrow_mut().push(new);
}
else
{
self.0.borrow_mut()[0] = new;
}
}
pub fn update_move<F>(&self, f: F)
where
F: Fn(T) -> T
{
if self.has_moved()
{
panic!("Movable already consumed!")
}
else
{
let v = self.consume();
self.insert(f(v));
}
}
}
use std::fmt::{Error, Formatter, Debug};
impl<T: Debug> Debug for Movable<T>
{
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>
{
if self.has_moved()
{
write!(f, "Movable(#MOVED#)")
}
else
{
write!(f, "Movable({:?})",
self.0.borrow().get(0).unwrap())
}
}
}