bulks 0.6.5

Amazing bulks! They are like iterators, but in bulk, and therefore support collection into arrays.
Documentation
use core::{marker::Destruct, ptr::Pointee};

use array_trait::length::{self, Length, LengthValue};

use crate::{Bulk, DoubleEndedBulk, RandomAccessBulk, InplaceBulk, InplaceBulkSpec, RandomAccessBulkSpec, SplitBulk};


/// A double-ended bulk with the direction inverted.
///
/// This `struct` is created by the [`rev`](Bulk::rev) method on [`Bulk`]. See its
/// documentation for more.
#[derive(Clone, Debug)]
#[must_use = "bulks are lazy and do nothing unless consumed"]
pub struct Rev<I>
where
    I: DoubleEndedBulk
{
    bulk: I,
}

impl<I> Rev<I>
where
    I: DoubleEndedBulk
{
    pub(crate) const fn new(bulk: I) -> Self
    {
        Self {
            bulk
        }
    }

    /// Consumes the `Rev`, returning the inner bulk.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use bulks::*;
    ///
    /// let s = b"foobar";
    /// let mut s2: [_; _] = s.bulk()
    ///     .copied()
    ///     .rev()
    ///     .into_inner()
    ///     .collect();
    /// assert_eq!(&s2, b"foobar");
    /// ```
    pub const fn into_inner(self) -> I
    {
        let Self { bulk } = self;
        bulk
    }
}

impl<I> const Default for Rev<I>
where
    I: ~const Bulk + DoubleEndedBulk + ~const Default
{
    fn default() -> Self
    {
        I::default().rev()
    }
}

impl<I> IntoIterator for Rev<I>
where
    I: DoubleEndedBulk
{
    type IntoIter = core::iter::Rev<I::IntoIter>;
    type Item = I::Item;

    fn into_iter(self) -> Self::IntoIter
    {
        self.into_inner().into_iter().rev()
    }
}
impl<I> const Bulk for Rev<I>
where
    I: ~const Bulk + ~const DoubleEndedBulk
{
    type MinLength = I::MinLength;
    type MaxLength = I::MaxLength;
    
    fn len(&self) -> usize
    {
        let Self { bulk } = self;
        bulk.len()
    }
    fn is_empty(&self) -> bool
    {
        let Self { bulk } = self;
        bulk.is_empty()
    }
    fn for_each<F>(self, f: F)
    where
        Self: Sized,
        F: ~const FnMut(Self::Item) + ~const Destruct
    {
        let Self { bulk } = self;
        bulk.rev_for_each(f);
    }
    fn try_for_each<F, R>(self, f: F) -> R
    where
        Self: Sized,
        Self::Item: ~const Destruct,
        F: ~const FnMut(Self::Item) -> R + ~const Destruct,
        R: ~const core::ops::Try<Output = (), Residual: ~const Destruct>
    {
        let Self { bulk } = self;
        bulk.try_rev_for_each(f)
    }
}
impl<I> const DoubleEndedBulk for Rev<I>
where
    I: ~const Bulk + ~const DoubleEndedBulk
{
    fn rev_for_each<F>(self, f: F)
    where
        Self: Sized,
        F: ~const FnMut(Self::Item) + ~const Destruct
    {
        let Self { bulk } = self;
        bulk.for_each(f);
    }
    fn try_rev_for_each<F, R>(self, f: F) -> R
    where
        Self: Sized,
        Self::Item: ~const Destruct,
        F: ~const FnMut(Self::Item) -> R + ~const Destruct,
        R: ~const core::ops::Try<Output = (), Residual: ~const Destruct>
    {
        let Self { bulk } = self;
        bulk.try_for_each(f)
    }
}
impl<I, N, L, R> const SplitBulk<L> for Rev<I>
where
    I: ~const SplitBulk<R, Left: ~const Bulk + DoubleEndedBulk, Right: ~const Bulk + DoubleEndedBulk> + ~const Bulk<Length: Length<Value = N> + Pointee<Metadata = N::Metadata>> + ~const DoubleEndedBulk,
    N: LengthValue<SaturatingSub<L> = R>,
    L: LengthValue,
    R: LengthValue
{
    type Left = Rev<I::Right>;
    type Right = Rev<I::Left>;

    fn split_at(Self { bulk }: Self, m: L) -> (Self::Left, Self::Right)
    where
        Self: Sized
    {
        let n = bulk.length();
        let (left, right) = bulk.split_at(length::value::saturating_sub(n, m));
        (
            right.rev(),
            left.rev()
        )
    }
}

impl<I> const RandomAccessBulk for Rev<I>
where
    I: for<'a, 'b> ~const RandomAccessBulk<ItemPointee: 'b,
        EachRef<'a>: ~const RandomAccessBulk<EachRef<'b> = I::EachRef<'b>> + 'b + ~const DoubleEndedBulk
    > + ~const DoubleEndedBulk
{
    type ItemPointee = I::ItemPointee;
    type EachRef<'a> = Rev<I::EachRef<'a>>
    where
        Self::ItemPointee: 'a,
        Self: 'a;

    fn each_ref<'a>(Self { bulk }: &'a Self) -> Self::EachRef<'a>
    where
        Self::ItemPointee: 'a,
        Self: 'a
    {
        bulk.each_ref().rev()
    }
}
impl<I> const InplaceBulk for Rev<I>
where
    I: for<'a, 'b> ~const InplaceBulk<ItemPointee: 'b,
        EachRef<'a>: ~const RandomAccessBulk<EachRef<'b> = I::EachRef<'b>> + 'b + ~const DoubleEndedBulk,
        EachMut<'a>: ~const InplaceBulk<EachRef<'b> = I::EachRef<'b>, EachMut<'b> = I::EachMut<'b>> + 'b + ~const DoubleEndedBulk
    > + ~const DoubleEndedBulk
{
    type EachMut<'a> = Rev<I::EachMut<'a>>
    where
        Self::ItemPointee: 'a,
        Self: 'a;

    fn each_mut<'a>(Self { bulk }: &'a mut Self) -> Self::EachMut<'a>
    where
        Self::ItemPointee: 'a,
        Self: 'a
    {
        bulk.each_mut().rev()
    }
}

impl<I> const RandomAccessBulkSpec for Rev<I>
where
    I: for<'a, 'b> ~const RandomAccessBulk<ItemPointee: 'b,
        EachRef<'a>: ~const RandomAccessBulk<EachRef<'b> = I::EachRef<'b>> + 'b + ~const DoubleEndedBulk
    > + ~const DoubleEndedBulk
{
    fn _get<'a, L>(Self { bulk }: &'a Self, i: L) -> Option<&'a <Self as RandomAccessBulk>::ItemPointee>
    where
        L: LengthValue,
        Self: 'a
    {
        if let Some(ip1) = length::value::checked_add(i, [(); 1]) && let Some(j) = length::value::checked_sub(bulk.length(), ip1)
        {
            bulk.get(j)
        }
        else
        {
            None
        }
    }
}
impl<I> const InplaceBulkSpec for Rev<I>
where
    I: for<'a, 'b> ~const InplaceBulk<ItemPointee: 'b,
        EachRef<'a>: ~const RandomAccessBulk<EachRef<'b> = I::EachRef<'b>> + 'b + ~const DoubleEndedBulk,
        EachMut<'a>: ~const InplaceBulk<EachRef<'b> = I::EachRef<'b>, EachMut<'b> = I::EachMut<'b>> + 'b + ~const DoubleEndedBulk
    > + ~const DoubleEndedBulk
{
    fn _get_mut<'a, L>(bulk: &'a mut Self, i: L) -> Option<&'a mut <Self as RandomAccessBulk>::ItemPointee>
    where
        L: LengthValue,
        Self: 'a
    {
        if let Some(ip1) = length::value::checked_add(i, [(); 1]) && let Some(j) = length::value::checked_sub(bulk.length(), ip1)
        {
            bulk.get_mut(j)
        }
        else
        {
            None
        }
    }
}

#[cfg(test)]
mod test
{
    use crate::*;

    #[test]
    fn it_works()
    {
        let a = [1, 2, 3, 4, 5, 6];
        let mut b = a.into_bulk();
            //.rev();
        b.each_mut()
            .for_each(|x| *x = 7 - *x);
        let b = b.collect_array();

        println!("b = {b:?}");
    }
}