use std::{
iter::{Enumerate, Filter, Flatten, Map, Rev, Skip, SkipWhile, Take, TakeWhile, Zip},
ops::{BitOr, Deref},
};
pub struct range<I>(pub I);
impl<I> Iterator for range<I>
where
I: Iterator,
{
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
impl<I> Deref for range<I> {
type Target = I;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<I> range<I>
where
I: Iterator,
{
pub fn begin(&mut self) -> I::Item {
self.0.next().unwrap()
}
}
pub trait adaptor<I> {
type Output;
fn pipe(self, i: I) -> Self::Output;
}
impl<I, V> BitOr<V> for range<I>
where
V: adaptor<I>,
{
type Output = range<V::Output>;
fn bitor(self, rhs: V) -> Self::Output {
range(rhs.pipe(self.0))
}
}
#[macro_export]
macro_rules! iota {
($value:expr) => {
$crate::views::iter(($value)..)
};
($first:expr, $last:expr) => {
$crate::views::iter(($first)..($last))
};
}
#[macro_export]
macro_rules! closed_iota {
($value:expr) => {
$crate::views::iter(($value)..)
};
($first:expr, $last:expr) => {
$crate::views::iter(($first)..=($last))
};
}
pub struct repeat(pub usize);
impl<I> adaptor<I> for repeat
where
I: Iterator + Clone,
{
type Output = Flatten<Take<std::iter::Repeat<I>>>;
fn pipe(self, i: I) -> Self::Output {
std::iter::repeat(i).take(self.0).flatten()
}
}
pub struct filter<F>(pub F);
impl<I, F> adaptor<I> for filter<F>
where
I: Iterator,
F: FnMut(&I::Item) -> bool,
{
type Output = Filter<I, F>;
fn pipe(self, i: I) -> Self::Output {
i.filter(self.0)
}
}
pub struct transform<F>(pub F);
impl<I, F, O> adaptor<I> for transform<F>
where
I: Iterator,
F: FnMut(I::Item) -> O,
{
type Output = Map<I, F>;
fn pipe(self, i: I) -> Self::Output {
i.map(self.0)
}
}
pub struct take(pub usize);
impl<I> adaptor<I> for take
where
I: Iterator,
{
type Output = Take<I>;
fn pipe(self, i: I) -> Self::Output {
i.take(self.0)
}
}
pub struct take_while<F>(pub F);
impl<I, F> adaptor<I> for take_while<F>
where
I: Iterator,
F: FnMut(&I::Item) -> bool,
{
type Output = TakeWhile<I, F>;
fn pipe(self, i: I) -> Self::Output {
i.take_while(self.0)
}
}
pub struct drop(pub usize);
impl<I> adaptor<I> for drop
where
I: Iterator,
{
type Output = Skip<I>;
fn pipe(self, i: I) -> Self::Output {
i.skip(self.0)
}
}
pub struct drop_while<F>(pub F);
impl<I, F> adaptor<I> for drop_while<F>
where
I: Iterator,
F: FnMut(&I::Item) -> bool,
{
type Output = SkipWhile<I, F>;
fn pipe(self, i: I) -> Self::Output {
i.skip_while(self.0)
}
}
pub struct join;
impl<I> adaptor<I> for join
where
I: Iterator,
I::Item: Iterator,
{
type Output = Flatten<I>;
fn pipe(self, i: I) -> Self::Output {
i.flatten()
}
}
pub struct reverse;
impl<I> adaptor<I> for reverse
where
I: DoubleEndedIterator,
{
type Output = Rev<I>;
fn pipe(self, i: I) -> Self::Output {
i.rev()
}
}
pub struct enumerate;
impl<I> adaptor<I> for enumerate
where
I: Iterator,
{
type Output = Enumerate<I>;
fn pipe(self, i: I) -> Self::Output {
i.enumerate()
}
}
pub struct zip<J>(J);
impl<I, J> adaptor<I> for zip<J>
where
I: Iterator,
J: IntoIterator,
{
type Output = Zip<I, J::IntoIter>;
fn pipe(self, i: I) -> Self::Output {
i.zip(self.0)
}
}