1#![cfg_attr(feature="cargo-clippy", allow(implicit_hasher))]
4
5use super::*;
10
11use std::hash::Hash;
12use std::vec::Vec;
13use std::rc::Rc;
14use std::sync::Arc;
15use std::collections::*;
16
17use proptest::collection::*;
18
19type RangedParams1<A> = product_type![SizeBounds, A];
25
26type RangedParams2<A, B> = product_type![SizeBounds, A, B];
28
29macro_rules! impl_1 {
30 ($typ: ident, $strat: ident, $($bound : path),* => $fun: ident) => {
31 arbitrary!([A: Arbitrary<'a> $(+ $bound)*] $typ<A>,
32 $strat<A::Strategy>, RangedParams1<A::Parameters>;
33 args => {
34 let product_unpack![range, a] = args;
35 $fun(any_with::<A>(a), range.into())
36 });
37 };
38}
39
40macro_rules! impl_2 {
41 ($typ: ident, $strat: ident, $($bound : path),* => $fun: ident) => {
42 arbitrary!([A: Arbitrary<'a> $(+ $bound)*, B: Arbitrary<'a>]
43 $typ<A, B>, $strat<A::Strategy, B::Strategy>,
44 RangedParams2<A::Parameters, B::Parameters>;
45 args => {
46 let product_unpack![range, a, b] = args;
47 $fun(any_with::<A>(a), any_with::<B>(b), range.into())
48 });
49 };
50}
51
52macro_rules! dst_wrapped {
57 ($($w: ident),*) => {
58 $(arbitrary!([A: Arbitrary<'a>] $w<[A]>,
59 FMapped<'a, Vec<A>, Self>, <Vec<A> as Arbitrary<'a>>::Parameters;
60 a => any_with_sinto::<Vec<A>, _>(a)
61 );)*
62 };
63}
64
65impl_1!(Vec, VecStrategy, => vec);
66dst_wrapped!(Box, Rc, Arc);
67impl_1!(VecDeque, VecDequeStrategy, => vec_deque);
68impl_1!(LinkedList, LinkedListStrategy, => linked_list);
69impl_1!(BTreeSet, BTreeSetStrategy, Ord => btree_set);
70impl_1!(BinaryHeap, BinaryHeapStrategy, Ord => binary_heap);
71impl_1!(HashSet, HashSetStrategy, Hash, Eq => hash_set);
72impl_2!(HashMap, HashMapStrategy, Hash, Eq => hash_map);
73
74impl<'a, A, B> Arbitrary<'a> for BTreeMap<A, B>
79where
80 A: Arbitrary<'static> + Ord,
81 B: Arbitrary<'static>,
82 StrategyFor<A>: 'static,
83 StrategyFor<B>: 'static,
84{
85 valuetree!();
86 type Parameters = RangedParams2<A::Parameters, B::Parameters>;
87 type Strategy = BTreeMapStrategy<A::Strategy, B::Strategy>;
88 fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
89 let product_unpack![range, a, b] = args;
90 btree_map(any_with::<A>(a), any_with::<B>(b), range.into())
91 }
92}
93
94macro_rules! into_iter_1 {
99 ($module: ident, $type: ident $(, $bound : path)*) => {
100 arbitrary!([A: Arbitrary<'a> $(+ $bound)*]
101 $module::IntoIter<A>,
102 SMapped<'a, $type<A>, Self>,
103 <$type<A> as Arbitrary<'a>>::Parameters;
104 args => any_with_smap(args, $type::into_iter));
105 };
106}
107
108macro_rules! into_iter_2 {
109 ($module: ident, $type: ident $(, $bound : path)*) => {
110 arbitrary!([A: Arbitrary<'a> $(+ $bound)*, B: Arbitrary<'a>]
111 $module::IntoIter<A, B>,
112 SMapped<'a, $type<A, B>, Self>,
113 <$type<A, B> as Arbitrary<'a>>::Parameters;
114 args => any_with_smap(args, $type::into_iter));
115 };
116}
117
118use std::vec;
119into_iter_1!(vec, Vec);
120use std::collections::vec_deque;
121into_iter_1!(vec_deque, VecDeque);
122use std::collections::linked_list;
123into_iter_1!(linked_list, LinkedList);
124use std::collections::btree_set;
125into_iter_1!(btree_set, BTreeSet, Ord);
126use std::collections::binary_heap;
127into_iter_1!(binary_heap, BinaryHeap, Ord);
128use std::collections::hash_set;
129into_iter_1!(hash_set, HashSet, Hash, Eq);
130use std::collections::hash_map;
131into_iter_2!(hash_map, HashMap, Hash, Eq);
132
133use std::collections::btree_map;
134
135impl<'a, A, B> Arbitrary<'a> for btree_map::IntoIter<A, B>
136where
137 A: Arbitrary<'static> + Ord,
138 B: Arbitrary<'static>,
139 StrategyFor<A>: 'static,
140 StrategyFor<B>: 'static,
141{
142 valuetree!();
143 type Parameters = <BTreeMap<A, B> as Arbitrary<'a>>::Parameters;
144 type Strategy = SMapped<'a, BTreeMap<A, B>, Self>;
145 fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
146 any_with_smap(args, BTreeMap::into_iter)
147 }
148}
149
150impl<'a, A: Arbitrary<'a> + Clone> Arbitrary<'a> for Bound<A>
155where
156 ParamsType<'a, A>: Clone,
157{
158 valuetree!();
159 type Parameters = A::Parameters;
160 type Strategy =
161 TupleUnion<(
162 W<SMapped<'a, A, Self>>,
163 W<SMapped<'a, A, Self>>,
164 W<Just<Self>>
165 )>;
166
167 fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
168 prop_oneof![
169 2 => any_with_smap(args.clone(), Bound::Included),
170 2 => any_with_smap(args, Bound::Excluded),
171 1 => Just(Bound::Unbounded),
172 ]
173 }
174}
175
176#[cfg(test)]
177mod test {
178 no_panic_test!(
179 vec => Vec<u8>,
180 box_slice => Box<[u8]>,
181 rc_slice => Rc<[u8]>,
182 arc_slice => Arc<[u8]>,
183 vec_deque => VecDeque<u8>,
184 linked_list => LinkedList<u8>,
185 btree_set => BTreeSet<u8>,
186 btree_map => BTreeMap<u8, u8>,
187 hash_set => HashSet<u8>,
188 hash_map => HashMap<u8, u8>,
189 bound => Bound<u8>,
190 binary_heap => BinaryHeap<u8>,
191 into_iter_vec => vec::IntoIter<u8>,
192 into_iter_vec_deque => vec_deque::IntoIter<u8>,
193 into_iter_linked_list => linked_list::IntoIter<u8>,
194 into_iter_binary_heap => binary_heap::IntoIter<u8>,
195 into_iter_btree_set => btree_set::IntoIter<u8>,
196 into_iter_btree_map => btree_map::IntoIter<u8, u8>,
197 into_iter_hash_set => hash_set::IntoIter<u8>,
198 into_iter_hash_map => hash_map::IntoIter<u8, u8>
199 );
200}