use core::ops::Deref;
use crate::alloc::{
rc::Rc,
sync::Arc
};
macro_rules! maybe {
($(#[$target_meta:meta])* $target_vis:vis $target_ty:ident $($target_tt:tt)+) => {
::paste::paste! {
$(#[$target_meta])*
$target_vis enum [< Maybe $target_ty >] $($target_tt)+ {
Owned(T),
$target_ty ($target_ty $($target_tt)+)
}
impl<T> Deref for [< Maybe $target_ty >] $($target_tt)+ {
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
Self::Owned(inner) => inner,
Self:: $target_ty (inner) => inner
}
}
}
impl<T> [< Maybe $target_ty >] $($target_tt)+
where
$target_ty <T> : Clone
{
pub fn make_clone(self) -> (Self, Self) {
match self {
Self::Owned(inner) => {
let shared_value = $target_ty :: from(inner);
(
Self:: $target_ty ( <$target_ty <T> as Clone>::clone(&shared_value) ), Self:: $target_ty ( shared_value )
)
},
Self:: $target_ty (ref inner) => (Self:: $target_ty (<$target_ty <T> as Clone>::clone(inner)), self)
}
}
}
impl<T> From<T> for [< Maybe $target_ty >] <T>
{
fn from(target_value: T) -> Self {
Self::Owned(target_value)
}
}
impl<T> From< $target_ty <T>> for [< Maybe $target_ty >] <T>
{
fn from(target_value: $target_ty <T>) -> Self {
Self :: $target_ty (target_value)
}
}
}
};
}
maybe!(
pub Rc<T>
);
maybe!(
pub Arc<T>
);