pub mod impls;
pub trait CheapClone {
fn cheap_clone(&self) -> Self;
}
pub trait CheapClonedOption
{
type Inner: CheapClone;
fn cheap_cloned(self) -> Option<Self::Inner>;
}
pub trait CheapClonedResult
{
type Inner: CheapClone;
type Error;
fn cheap_cloned(self) -> Result<Self::Inner, Self::Error>;
}
impl<T: CheapClone> CheapClonedOption for Option<&T> {
type Inner = T;
fn cheap_cloned(self) -> Option<T> {
self.map(|v| v.cheap_clone())
}
}
impl<T: CheapClone, E> CheapClonedResult for Result<&T, E> {
type Inner = T;
type Error = E;
fn cheap_cloned(self) -> Result<Self::Inner, Self::Error> {
self.map(|v| v.cheap_clone())
}
}
#[cfg(test)]
mod tests {
use crate::CheapClone;
use crate::CheapClonedOption;
use crate::CheapClonedResult;
#[derive(PartialEq, Debug)]
struct A(u8);
impl CheapClone for A {
fn cheap_clone(&self) -> Self {
Self(self.0)
}
}
#[test]
fn cheap_clone_primitive() {
let a = 1;
assert_eq!(a, a.cheap_clone());
}
#[test]
fn cheap_cloned_option() {
let a = Some(A(4));
let a_ref = a.as_ref();
let a_cloned = a_ref.cheap_cloned();
assert_eq!(a, a_cloned);
}
#[test]
fn cheap_cloned_result() {
let a: Result<A, ()> = core::hint::black_box(Ok(A(4)));
let a_ref = a.as_ref();
let a_cloned = a_ref.cheap_cloned().unwrap();
assert_eq!(a.unwrap(), a_cloned);
}
}