asynciter 0.1.0

Asynchronous iterator.
Documentation
use asynciter::{AsyncIterator, IntoAsyncIterator, ToAsyncIterator};

#[tokio::test]
async fn test_awaited() {
    let v = vec![1, 2, 3, 4];
    let mut iter = v.into_aiter().map(|s| async move { s + 1 }).awaited();
    while let Some(s) = iter.next().await {
        println!("{}", s);
    }
}

#[tokio::test]
async fn test_map() {
    let v = vec![1, 2, 3, 4];
    let mut iter = v.into_aiter().map(|s| s + 1);
    while let Some(s) = iter.next().await {
        println!("{}", s);
    }
}

#[tokio::test]
async fn test_async_map() {
    let v = vec![1, 2, 3, 4];
    async fn do_async(v: i32) -> i32 {
        v + 5
    }
    let mut iter = v.into_aiter().amap(do_async);
    while let Some(s) = iter.next().await {
        println!("{}", s);
    }
}

#[tokio::test]
async fn test_enumerate() {
    let v: Vec<i32> = vec![1, 2, 3, 4];
    let val: Vec<_> = v.into_aiter().enumerate().collect().await;
    assert_eq!(val, [(0, 1), (1, 2), (2, 3), (3, 4)]);
}

#[tokio::test]
async fn test_peekable() {
    let v: Vec<i32> = vec![1, 2, 3, 4, 5];
    let mut p = v.into_aiter().peekable();
    assert_eq!(p.peek().await, Some(&1));
    assert_eq!(p.next().await, Some(1));
    assert_eq!(p.peek().await, Some(&2));
    assert_eq!(p.next_if(|s| s % 2 == 0).await, Some(2));
    assert_eq!(p.peek().await, Some(&3));
    assert_eq!(p.next().await, Some(3));
    assert_eq!(p.next_if_eq(&3).await, None);
    assert_eq!(p.peek().await, Some(&4));
}

#[tokio::test]
async fn test_copied_cloned() {
    let v: Vec<i32> = vec![1, 2, 3, 4, 5];
    assert_eq!(v, v.iter().into_aiter().copied().collect::<Vec<_>>().await);

    let v: Vec<String> = (0..5i32).map(|s| s.to_string()).collect();
    assert_eq!(v, v.iter().into_aiter().cloned().collect::<Vec<_>>().await);
}

#[tokio::test]
async fn test_filter() {
    let v: Vec<i32> = vec![1, 2, 3, 4, 5];
    assert_eq!(
        vec![2, 4],
        v.clone()
            .into_iter()
            .into_aiter()
            .filter(|s| s % 2 == 0)
            .collect::<Vec<_>>()
            .await
    );
    assert_eq!(
        vec!["2".to_string(), "4".into()],
        v.clone()
            .into_iter()
            .into_aiter()
            .filter_map(|s| if s % 2 == 0 {
                Some(s.to_string())
            } else {
                None
            })
            .collect::<Vec<_>>()
            .await
    );
    assert_eq!(
        vec![2, 4],
        v.clone()
            .into_iter()
            .into_aiter()
            .afilter(|s| {
                let s = *s;
                async move { s % 2 == 0 }
            })
            .collect::<Vec<i32>>()
            .await
    );
    async fn fmap_async(s: i32) -> Option<String> {
        if s % 2 == 0 {
            Some(s.to_string())
        } else {
            None
        }
    }
    assert_eq!(
        vec!["2".to_string(), "4".into()],
        v.clone()
            .into_iter()
            .into_aiter()
            .afilter_map(fmap_async)
            .collect::<Vec<_>>()
            .await
    );
}

#[tokio::test]
async fn test_inspect() {
    let v: Vec<i32> = vec![1, 2, 3, 4, 5];
    let mut it = v.into_iter().into_aiter().inspect(|s| println!("{}", s));

    while it.next().await.is_some() {}
}

#[tokio::test]
async fn test_for_each() {
    let v: Vec<i32> = vec![1, 2, 3, 4, 5];
    v.clone()
        .into_aiter()
        .map(|s| s + 1)
        .for_each(|s| println!("{}", s))
        .await;

    async fn do_async(val: i32) {
        let res = val + 5;
        println!("{}", res);
    }
    v.into_aiter().afor_each(do_async).await;
}

#[tokio::test]
async fn test_fuse() {
    #[derive(Debug, Default)]
    struct MaybeNone {
        inner: i32,
    }

    impl AsyncIterator for MaybeNone {
        type Item = i32;

        async fn next(&mut self) -> Option<i32> {
            let res = if self.inner % 4 == 3 {
                None
            } else {
                Some(self.inner)
            };
            self.inner += 1;
            res
        }
    }

    let mbn: MaybeNone = Default::default();
    let res: Vec<i32> = mbn.fuse().collect::<Vec<_>>().await;
    assert_eq!(vec![0, 1, 2], res);
}

#[tokio::test]
async fn test_flatten() {
    let res = (0..5i32)
        .into_aiter()
        .map(|s| (0..=s).collect::<Vec<_>>())
        .flatten()
        .collect::<Vec<_>>()
        .await;
    assert_eq!(vec![0, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4], res);
    let res = (0..5i32)
        .into_aiter()
        .flat_map(|s| (0..=s).collect::<Vec<_>>())
        .collect::<Vec<_>>()
        .await;
    assert_eq!(vec![0, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4], res);

    async fn do_async(val: i32) -> Vec<i32> {
        (0..val).collect()
    }
    let res = (1..5i32)
        .into_aiter()
        .aflat_map(do_async)
        .collect::<Vec<_>>()
        .await;
    assert_eq!(vec![0, 0, 1, 0, 1, 2, 0, 1, 2, 3], res);
}

#[tokio::test]
async fn test_reduce() {
    let reduced: i32 = (1..10).into_aiter().reduce(|acc, e| acc + e).await.unwrap();
    assert_eq!(reduced, 45);
    async fn do_async(acc: i32, e: i32) -> i32 {
        acc + e
    }
    let reduced: i32 = (1..10).into_aiter().areduce(do_async).await.unwrap();
    assert_eq!(reduced, 45);
}

#[tokio::test]
async fn test_zip() {
    let res = (0..=3)
        .into_aiter()
        .zip((0..=3).rev())
        .collect::<Vec<_>>()
        .await;
    assert_eq!(vec![(0, 3), (1, 2), (2, 1), (3, 0)], res);
}

#[tokio::test]
async fn test_count() {
    let res = (0..15).into_aiter().count().await;
    assert_eq!(res, 15);
}

#[tokio::test]
async fn test_all() {
    assert!(
        (0..15)
            .aiter()
            .filter(|s| s % 2 == 0)
            .all(|s| s % 2 == 0)
            .await
    );
    async fn check_async(val: i32) -> bool {
        val % 2 == 0
    }
    assert!(
        (0..15)
            .aiter()
            .filter(|s| s % 2 == 0)
            .aall(check_async)
            .await
    );
}

#[tokio::test]
async fn test_any() {
    assert!((0..15).aiter().any(|s| s == 5).await);
    async fn check_async(val: i32) -> bool {
        val % 2 == 0
    }
    assert!((0..15).aiter().aany(check_async).await);
}

#[tokio::test]
async fn test_intersperse() {
    let vec: Vec<i32> = (0..3).aiter().intersperse(5).collect().await;
    assert_eq!(vec, vec![0, 5, 1, 5, 2]);
    let string: String = ["Hello", "World", "!"]
        .iter()
        .aiter()
        .copied()
        .intersperse_with(|| " ")
        .collect()
        .await;
    assert_eq!(string, "Hello World !".to_string());
    async fn get_whitespace() -> &'static str {
        " "
    }
    let string: String = ["Hello", "World", "!"]
        .iter()
        .aiter()
        .copied()
        .aintersperse_with(get_whitespace)
        .collect()
        .await;
    assert_eq!(string, "Hello World !".to_string());
}

#[tokio::test]
async fn test_take() {
    let res: Vec<i32> = (0..10).aiter().take(5).collect().await;
    assert_eq!(res, vec![0, 1, 2, 3, 4]);
}

#[tokio::test]
async fn test_cycle() {
    let res: Vec<i32> = (0..3).aiter().cycle().take(5).collect().await;
    assert_eq!(res, vec![0, 1, 2, 0, 1]);
}

#[tokio::test]
async fn test_scan() {
    let a = [1, 2, 3, 4];

    let iter = a.iter().aiter().scan(1, |state, &x| {
        // each iteration, we'll multiply the state by the element ...
        *state *= x;

        // ... and terminate if the state exceeds 6
        if *state > 6 {
            return None;
        }
        // ... else yield the negation of the state
        Some(-*state)
    });

    assert_eq!(vec![-1, -2, -6], iter.collect::<Vec<_>>().await);

    let a = [1, 2, 3, 4];

    let iter = a.iter().aiter().ascan(1, |state, &x| {
        *state *= x;

        let imut_state = *state;

        async move {
            if imut_state > 6 {
                return None;
            }
            Some(-imut_state)
        }
    });

    assert_eq!(vec![-1, -2, -6], iter.collect::<Vec<_>>().await);
}

#[tokio::test]
async fn test_take_while() {
    let it: Vec<_> = (0..10).aiter().take_while(|s| *s < 5).collect().await;
    assert_eq!(vec![0, 1, 2, 3, 4], it);
    let it: Vec<_> = (0..10)
        .aiter()
        .atake_while(|s| {
            let s = *s;
            async move { s < 5 }
        })
        .collect()
        .await;
    assert_eq!(vec![0, 1, 2, 3, 4], it);
}

#[tokio::test]
async fn test_debug() {
    let it = (0..3).aiter().map(|s| s + 1).amap(|s| async move { s - 1 });
    println!("{:#?}", it);
}

#[tokio::test]
async fn test_clone() {
    let it = (0..3).aiter().map(|s| s + 1).amap(|s| async move { s - 1 });
    println!("{:#?}", it.clone());
}