pub struct ValueBox<T> {
ptr: Option<Box<T>>,
}
impl<T> ValueBox<T> {
pub fn empty() -> Self {
ValueBox { ptr: None }
}
pub fn new(value: T) -> Self {
ValueBox {
ptr: Some(Box::new(value)),
}
}
pub fn is_empty(&self) -> bool {
self.ptr.is_none()
}
pub fn get(&self) -> Option<&T> {
self.ptr.as_deref()
}
pub fn get_mut(&mut self) -> Option<&mut T> {
self.ptr.as_deref_mut()
}
pub fn swap(&mut self, other: &mut ValueBox<T>) {
std::mem::swap(&mut self.ptr, &mut other.ptr);
}
}
impl<T: Clone> Clone for ValueBox<T> {
fn clone(&self) -> Self {
ValueBox {
ptr: self.ptr.clone(),
}
}
}
impl<T> Default for ValueBox<T> {
fn default() -> Self {
ValueBox::empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_and_filled() {
let empty: ValueBox<i32> = ValueBox::empty();
assert!(empty.is_empty());
assert!(empty.get().is_none());
let filled = ValueBox::new(7_i32);
assert!(!filled.is_empty());
assert_eq!(filled.get(), Some(&7));
}
#[test]
fn clone_is_a_deep_copy() {
let original = ValueBox::new(vec![1, 2, 3]);
let mut copy = original.clone();
copy.get_mut().unwrap().push(4);
assert_eq!(original.get().unwrap().len(), 3);
assert_eq!(copy.get().unwrap().len(), 4);
}
#[test]
fn swap_exchanges_contents() {
let mut a = ValueBox::new(1_i32);
let mut b = ValueBox::new(2_i32);
a.swap(&mut b);
assert_eq!(a.get(), Some(&2));
assert_eq!(b.get(), Some(&1));
}
}