pub use std::boxed::Box;
pub use std::rc::Rc;
pub use std::sync::Arc;
pub trait Data<T>: Clone {
fn new(value: T) -> Self;
fn get(&self) -> &T;
fn get_mut(&mut self) -> Option<&mut T>;
fn ptr_eq(&self, other: &Self) -> bool;
}
impl<T> Data<T> for Arc<T> {
fn new(value: T) -> Self {
Arc::new(value)
}
fn get(&self) -> &T {
&self
}
fn get_mut(&mut self) -> Option<&mut T> {
Arc::get_mut(self)
}
fn ptr_eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self, &other)
}
}
impl<T> Data<T> for Rc<T> {
fn new(value: T) -> Self {
Rc::new(value)
}
fn get(&self) -> &T {
&self
}
fn get_mut(&mut self) -> Option<&mut T> {
Rc::get_mut(self)
}
fn ptr_eq(&self, other: &Self) -> bool {
Rc::ptr_eq(&self, &other)
}
}
impl<T: Clone> Data<T> for Box<T> {
fn new(value: T) -> Self {
Box::new(value)
}
fn get(&self) -> &T {
&self
}
fn get_mut(&mut self) -> Option<&mut T> {
Some(self)
}
fn ptr_eq(&self, other: &Self) -> bool {
std::ptr::eq(&self, &other)
}
}
#[derive(Clone)]
pub struct Cloned<T>(T);
impl<T: Clone> Data<T> for Cloned<T> {
fn new(value: T) -> Self {
Cloned(value)
}
fn get(&self) -> &T {
&self.0
}
fn get_mut(&mut self) -> Option<&mut T> {
Some(&mut self.0)
}
fn ptr_eq(&self, other: &Self) -> bool {
std::ptr::eq(&self.0, &other.0)
}
}
#[cfg(test)]
fn test_i32<T: Data<i32>>() {
let mut number = T::new(16);
assert_eq!(number.get(), &16);
if let Some(number) = number.get_mut() {
*number += 4;
}
assert_eq!(number.get(), &20);
let clone = number.clone();
assert_eq!(clone.get(), number.get());
}
#[cfg(test)]
fn test_string<T: Data<String>>() {
let mut string = T::new("Hello".into());
assert_eq!(string.get(), "Hello");
if let Some(string) = string.get_mut() {
string.push_str(", World!");
}
assert_eq!(string.get(), "Hello, World!");
let clone = string.clone();
assert_eq!(clone.get(), string.get());
}
#[test]
fn test_all() {
test_i32::<Cloned<i32>>();
test_i32::<Arc<i32>>();
test_i32::<Rc<i32>>();
test_i32::<Box<i32>>();
test_string::<Cloned<String>>();
test_string::<Arc<String>>();
test_string::<Rc<String>>();
test_string::<Box<String>>();
}