proptest/arbitrary/_core/
iter.rs1use core::fmt;
13use core::iter::Fuse;
14use core::iter::*;
15
16use crate::arbitrary::*;
17use crate::strategy::statics::static_map;
18use crate::strategy::*;
19
20wrap_ctor!(Once, once);
24wrap_ctor!([Clone] Repeat, repeat);
25wrap_ctor!([Iterator + Clone] Cycle, Iterator::cycle);
26wrap_ctor!([Iterator] Enumerate, Iterator::enumerate);
27wrap_ctor!([Iterator] Fuse, Iterator::fuse);
28wrap_ctor!([Iterator<Item = T>, T: fmt::Debug] Peekable, Iterator::peekable);
29wrap_ctor!([DoubleEndedIterator] Rev, Iterator::rev);
30
31arbitrary!(['a, T: 'a + Clone, A: Arbitrary + Iterator<Item = &'a T>]
32 Cloned<A>, SMapped<A, Self>, A::Parameters;
33 args => static_map(any_with::<A>(args), Iterator::cloned));
34
35impl<
36 T: 'static + Clone,
37 A: fmt::Debug + 'static + Iterator<Item = &'static T>,
38 > functor::ArbitraryF1<A> for Cloned<A>
39{
40 type Parameters = ();
41
42 fn lift1_with<S>(base: S, _args: Self::Parameters) -> BoxedStrategy<Self>
43 where
44 S: Strategy<Value = A> + 'static,
45 {
46 base.prop_map(Iterator::cloned).boxed()
47 }
48}
49
50arbitrary!([A] Empty<A>; empty());
51
52arbitrary!(
53 [A: Arbitrary + Iterator, B: Arbitrary + Iterator]
54 Zip<A, B>, SMapped<(A, B), Self>,
55 product_type![A::Parameters, B::Parameters];
56 args => static_map(any_with::<(A, B)>(args), |(a, b)| a.zip(b))
57);
58
59lift1!(
60 [fmt::Debug + 'static + Iterator, B: 'static + Arbitrary + Iterator]
61 Zip<B, A>,
62 B::Parameters;
63 base, args =>
64 (any_with::<B>(args), base).prop_map(|(b, a)| b.zip(a)).boxed()
65);
66
67impl<A: fmt::Debug + Iterator, B: fmt::Debug + Iterator>
68 functor::ArbitraryF2<A, B> for Zip<A, B>
69{
70 type Parameters = ();
71
72 fn lift2_with<AS, BS>(
73 fst: AS,
74 snd: BS,
75 _args: Self::Parameters,
76 ) -> BoxedStrategy<Self>
77 where
78 AS: Strategy<Value = A> + 'static,
79 BS: Strategy<Value = B> + 'static,
80 {
81 (fst, snd).prop_map(|(a, b)| a.zip(b)).boxed()
82 }
83}
84
85arbitrary!(
86 [T,
87 A: Arbitrary + Iterator<Item = T>,
88 B: Arbitrary + Iterator<Item = T>]
89 Chain<A, B>, SMapped<(A, B), Self>,
90 product_type![A::Parameters, B::Parameters];
91 args => static_map(any_with::<(A, B)>(args), |(a, b)| a.chain(b))
92);
93
94lift1!([fmt::Debug + 'static + Iterator<Item = T>,
95 B: 'static + Arbitrary + Iterator<Item = T>,
96 T]
97 Chain<B, A>,
98 B::Parameters;
99 base, args =>
100 (any_with::<B>(args), base).prop_map(|(b, a)| b.chain(a)).boxed()
101);
102
103impl<
104 T,
105 A: fmt::Debug + Iterator<Item = T>,
106 B: fmt::Debug + Iterator<Item = T>,
107 > functor::ArbitraryF2<A, B> for Chain<A, B>
108{
109 type Parameters = ();
110
111 fn lift2_with<AS, BS>(
112 fst: AS,
113 snd: BS,
114 _args: Self::Parameters,
115 ) -> BoxedStrategy<Self>
116 where
117 AS: Strategy<Value = A> + 'static,
118 BS: Strategy<Value = B> + 'static,
119 {
120 (fst, snd).prop_map(|(a, b)| a.chain(b)).boxed()
121 }
122}
123
124macro_rules! usize_mod {
125 ($type: ident, $mapper: ident) => {
126 arbitrary!([A: Arbitrary + Iterator] $type<A>,
127 SMapped<(A, usize), Self>, A::Parameters;
128 a => static_map(
129 any_with::<(A, usize)>(product_pack![a, ()]),
130 |(a, b)| a.$mapper(b)
131 )
132 );
133
134 lift1!([Iterator] $type<A>;
135 base => (base, any::<usize>()).prop_map(|(a, b)| a.$mapper(b))
136 );
137 };
138}
139
140usize_mod!(Skip, skip);
141usize_mod!(Take, take);
142
143#[cfg(feature = "unstable")]
144usize_mod!(StepBy, step_by);
145
146#[cfg(test)]
147mod test {
148 use super::*;
149
150 use std::ops::Range;
151 const DUMMY: &'static [u8] = &[0, 1, 2, 3, 4];
152 #[derive(Debug)]
153 struct Dummy(u8);
154 arbitrary!(Dummy, SFnPtrMap<Range<u8>, Self>; static_map(0..5, Dummy));
155 impl Iterator for Dummy {
156 type Item = &'static u8;
157 fn next(&mut self) -> Option<Self::Item> {
158 if self.0 < 5 {
159 let r = &DUMMY[self.0 as usize];
160 self.0 += 1;
161 Some(r)
162 } else {
163 None
164 }
165 }
166 }
167
168 no_panic_test!(
169 empty => Empty<u8>,
170 once => Once<u8>,
171 repeat => Repeat<u8>,
172 cloned => Cloned<super::Dummy>,
173 cycle => Cycle<Once<u8>>,
174 enumerate => Enumerate<Repeat<u8>>,
175 fuse => Fuse<Once<u8>>,
176 peekable => Peekable<Repeat<u8>>,
177 rev => Rev<::std::vec::IntoIter<u8>>,
178 zip => Zip<Repeat<u8>, Repeat<u16>>,
179 chain => Chain<Once<u8>, Once<u8>>,
180 skip => Skip<Repeat<u8>>,
181 take => Take<Repeat<u8>>
182 );
183
184 #[cfg(feature = "unstable")]
185 no_panic_test!(
186 step_by => StepBy<Repeat<u8>>
187 );
188}