use std::rc::Rc;
use std::sync::Arc;
pub trait FromRc<T> {
fn from_rc(val: Rc<T>) -> Self;
fn from_arc(val: Arc<T>) -> Self;
}
impl<T> FromRc<T> for Rc<T>
where
T: Sized + Clone,
{
fn from_rc(val: Rc<T>) -> Self {
val.clone()
}
fn from_arc(val: Arc<T>) -> Self {
match Arc::<T>::try_unwrap(val) {
Ok(v) => Self::new(v),
Err(r) => Self::new(r.cloned()),
}
}
}
impl<T> FromRc<T> for Arc<T>
where
T: Sized + Clone,
{
fn from_rc(val: Rc<T>) -> Self {
match Rc::<T>::try_unwrap(val) {
Ok(v) => Self::new(v),
Err(r) => Self::new(r.cloned()),
}
}
fn from_arc(val: Arc<T>) -> Self {
val.clone()
}
}
impl<T> FromRc<T> for Box<T>
where
T: Sized + Clone,
{
fn from_rc(val: Rc<T>) -> Self {
match Rc::<T>::try_unwrap(val) {
Ok(v) => Self::new(v),
Err(r) => Self::new(r.cloned()),
}
}
fn from_arc(val: Arc<T>) -> Self {
match Arc::<T>::try_unwrap(val) {
Ok(v) => Self::new(v),
Err(r) => Self::new(r.cloned()),
}
}
}
pub trait Cloned<T> {
fn cloned(&self) -> T;
fn to_value_rc(&self) -> ValueRc<T>;
}
impl<T: Clone> Cloned<T> for Rc<T>
where
T: Sized + Clone,
{
fn cloned(&self) -> T {
(*self.as_ref()).clone()
}
fn to_value_rc(&self) -> ValueRc<T> {
ValueRc::from_rc(self.clone())
}
}
impl<T: Clone> Cloned<T> for Arc<T>
where
T: Sized + Clone,
{
fn cloned(&self) -> T {
(*self.as_ref()).clone()
}
fn to_value_rc(&self) -> ValueRc<T> {
ValueRc::from_arc(self.clone())
}
}
impl<T: Clone> Cloned<T> for Box<T>
where
T: Sized + Clone,
{
fn cloned(&self) -> T {
self.as_ref().clone()
}
fn to_value_rc(&self) -> ValueRc<T> {
ValueRc::new(self.cloned())
}
}
pub type ValueRc<T> = Arc<T>;