proptest_arbitrary/_std/
iter.rs

1//! Arbitrary implementations for `std::iter`.
2
3use super::*;
4use std::iter::*;
5use std::iter::Fuse;
6
7// TODO: Filter, FilterMap, FlatMap, Map, Inspect, Scan, SkipWhile
8// Might be possible with CoArbitrary
9
10wrap_ctor!(Once, once);
11wrap_ctor!([Clone] Repeat, repeat);
12wrap_ctor!([Iterator<Item = &'a T>, T: 'a + Clone] Cloned, Iterator::cloned);
13wrap_ctor!([Iterator + Clone] Cycle, Iterator::cycle);
14wrap_ctor!([Iterator] Enumerate, Iterator::enumerate);
15wrap_ctor!([Iterator] Fuse, Iterator::fuse);
16wrap_ctor!([Iterator<Item = T>, T: Debug] Peekable, Iterator::peekable);
17wrap_ctor!([DoubleEndedIterator] Rev, Iterator::rev);
18
19arbitrary!([A] Empty<A>; empty());
20
21arbitrary!(
22    [A: Arbitrary<'a> + Iterator, B: Arbitrary<'a> + Iterator]
23    Zip<A, B>, SMapped<'a, (A, B), Self>,
24    product_type![A::Parameters, B::Parameters];
25    args => any_with_smap(args, |(a, b)| a.zip(b))
26);
27
28arbitrary!(
29    [T,
30     A: Arbitrary<'a> + Iterator<Item = T>,
31     B: Arbitrary<'a> + Iterator<Item = T>]
32    Chain<A, B>, SMapped<'a, (A, B), Self>,
33    product_type![A::Parameters, B::Parameters];
34    args => any_with_smap(args, |(a, b)| a.chain(b))
35);
36
37macro_rules! usize_mod {
38    ($type: ident, $mapper: ident) => {
39        arbitrary!([A: Arbitrary<'a> + Iterator] $type<A>,
40            SMapped<'a, (A, usize), Self>, A::Parameters;
41            a => any_with_smap(product_pack![a, ()], |(a, b)| a.$mapper(b))
42        );
43    };
44}
45
46usize_mod!(Skip, skip);
47usize_mod!(Take, take);
48
49#[cfg(feature = "unstable")]
50usize_mod!(StepBy, step_by);
51
52#[cfg(test)]
53mod test {
54    use super::*;
55
56    use std::ops::Range;
57    const DUMMY: &'static [u8] = &[0, 1, 2, 3, 4];
58    #[derive(Debug)]
59    struct Dummy(u8);
60    arbitrary!(Dummy, SFnPtrMap<Range<u8>, Self>; static_map(0..5, Dummy));
61    impl Iterator for Dummy {
62        type Item = &'static u8;
63        fn next(&mut self) -> Option<Self::Item> {
64            if self.0 < 5 {
65                let r = &DUMMY[self.0 as usize];
66                self.0 += 1;
67                Some(r)
68            } else {
69                None
70            }
71        }
72    }
73
74    no_panic_test!(
75        empty     => Empty<u8>,
76        once      => Once<u8>,
77        repeat    => Repeat<u8>,
78        cloned    => Cloned<super::Dummy>,
79        cycle     => Cycle<Once<u8>>,
80        enumerate => Enumerate<Repeat<u8>>,
81        fuse      => Fuse<Once<u8>>,
82        peekable  => Peekable<Repeat<u8>>,
83        rev       => Rev<std::vec::IntoIter<u8>>,
84        zip       => Zip<Repeat<u8>, Repeat<u16>>,
85        chain     => Chain<Once<u8>, Once<u8>>,
86        skip      => Skip<Repeat<u8>>,
87        take      => Take<Repeat<u8>>
88    );
89
90    #[cfg(feature = "unstable")]
91    no_panic_test!(
92        step_by   => StepBy<Repeat<u8>>
93    );
94}