ref_clone 0.8.0

An implementation of borrows as higher kinded types that can be used to prevent code duplication.
use crate::*;

pub trait DerefRef {
    type Target: ?Sized;

    fn deref_ref<'a, S: RefType>(self: Ref<'a, Self, S>) -> Ref<'a, Self::Target, S>;
}

pub trait IndexRef<Idx> {
    type Output: ?Sized;

    fn index_ref<'a, S: RefType>(self: Ref<'a, Self, S>, index: Idx) -> Ref<'a, Self::Output, S>;
}

#[repr(transparent)]
pub struct RefIterator<'a, T: RefType, S, I: 'a>(S)
where
    S: Iterator<Item = Ref<'a, I, T>>;

impl<'a, S: Iterator<Item = Ref<'a, I, Shared>>, I> Iterator for RefIterator<'a, Shared, S, I> {
    type Item = &'a I;
    #[inline(always)]
    fn next(&mut self) -> Option<&'a I> {
        self.0.next().map(|x| x.as_ref())
    }
}

impl<'a, S: Iterator<Item = Ref<'a, I, Unique>>, I> Iterator for RefIterator<'a, Unique, S, I> {
    type Item = &'a mut I;
    #[inline(always)]
    fn next(&mut self) -> Option<&'a mut I> {
        self.0.next().map(|mut x| x.as_mut())
    }
}

pub trait IntoIteratorRef<'a> {
    type Item: 'a;
    type IntoIter<T: RefType>: Iterator<Item = Ref<'a, Self::Item, T>>;
    fn into_iter_ref<T: RefType>(self: Ref<'a, Self, T>) -> Self::IntoIter<T>;
    #[inline(always)]
    fn iter(&'a self) -> RefIterator<'a, Shared, Self::IntoIter<Shared>, Self::Item> {
        RefIterator(Ref::new(self).into_iter_ref())
    }
    #[inline(always)]
    fn iter_mut(&'a mut self) -> RefIterator<'a, Unique, Self::IntoIter<Unique>, Self::Item> {
        RefIterator(Ref::new(self).into_iter_ref())
    }
}

impl<'a, S, T: RefType> IntoIterator for Ref<'a, S, T>
where
    S: IntoIteratorRef<'a>,
{
    type Item = Ref<'a, S::Item, T>;
    type IntoIter = S::IntoIter<T>;
    #[inline(always)]
    fn into_iter(self) -> S::IntoIter<T> {
        self.into_iter_ref()
    }
}