#[macro_export]
macro_rules! try_to_clone {
(&$value:expr) => {{
#[allow(unused_imports)]
use $crate::cloning::{TryToCloneFallback, TryToCloneViaClone, TryToCloneViaCopy};
(&&&$crate::cloning::TryToClone(&$value)).try_to_phlow_clone()
}};
($value:expr) => {{
#[allow(unused_imports)]
use $crate::cloning::{TryToCloneFallback, TryToCloneViaClone, TryToCloneViaCopy};
(&&&$crate::cloning::TryToClone(&$value)).try_to_phlow_clone()
}};
}
pub struct TryToClone<'a, T>(pub &'a T);
pub trait TryToCloneViaCopy<T> {
fn try_to_phlow_clone(&self) -> Option<T>;
}
impl<T: Copy> TryToCloneViaCopy<T> for &&TryToClone<'_, T> {
fn try_to_phlow_clone(&self) -> Option<T> {
Some(*self.0)
}
}
pub trait TryToCloneViaClone<T> {
fn try_to_phlow_clone(&self) -> Option<T>;
}
impl<T: Clone> TryToCloneViaClone<T> for &TryToClone<'_, T> {
fn try_to_phlow_clone(&self) -> Option<T> {
Some(self.0.clone())
}
}
pub trait TryToCloneFallback<T> {
fn try_to_phlow_clone(&self) -> Option<T>;
}
impl<T> TryToCloneFallback<T> for TryToClone<'_, T> {
fn try_to_phlow_clone(&self) -> Option<T> {
None
}
}
#[cfg(test)]
mod tests {
#[derive(Debug, PartialEq, Eq)]
struct CloneOnly(&'static str);
impl Clone for CloneOnly {
fn clone(&self) -> Self {
Self(self.0)
}
}
#[test]
fn try_to_clone_macro_is_usable_within_the_crate() {
let value = CloneOnly("hello");
assert_eq!(try_to_clone!(&value), Some(CloneOnly("hello")));
}
}