cheapclone 0.1.0

Mark a type, whose clone operation is cheap.
Documentation
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);
    }

}