@@ -16,6 +16,7 @@ use std::collections::*;
16
16
use std:: fmt;
17
17
use std:: hash:: Hash ;
18
18
use std:: ops:: Range ;
19
+ use std:: slice;
19
20
20
21
use bit_set:: BitSet ;
21
22
use rand;
@@ -25,6 +26,143 @@ use strategy::*;
25
26
use tuple:: TupleValueTree ;
26
27
use test_runner:: * ;
27
28
29
+ // TODO: add more CollectionStrategy impls for different types such as
30
+ // HashSet.
31
+
32
+ // TODO: tests for CollectionStrategy impls.
33
+
34
+ /// Returns a `Strategy` that generates subsequences of `source` where the
35
+ /// where the subsequences have a size: `size.start <= seq.len() < size.end`.
36
+ pub fn subsequence < T > ( source : Vec < T > , size : Range < usize > ) -> SubseqStrategy < T >
37
+ where
38
+ T : Clone + fmt:: Debug
39
+ {
40
+ source. prop_sample ( size)
41
+ }
42
+
43
+ /// A collection, such as `Vec<T>` is itself a strategy to create samples
44
+ /// (or in the case of `Vec`: subsequences) with the elements of the collection.
45
+ pub trait CollectionStrategy : Sized + fmt:: Debug {
46
+ /// The `Strategy` generating the samples.
47
+ type Strategy : Strategy < Value = Self :: ValueTree > ;
48
+
49
+ /// Always the same as `Self::Strategy::Value`.
50
+ /// Unfortunately this can't be removed until `impl Trait` lands.
51
+ type ValueTree : ValueTree < Value = Self > ;
52
+
53
+ /// Constructs a `Strategy` to generate samples of `self` given a range
54
+ /// (low..high) where the output sample has a number of elements: len.
55
+ /// The following always holds for the sample: `low <= len < high`.
56
+ ///
57
+ /// # Safety
58
+ ///
59
+ /// A panic must occur at least when:
60
+ ///
61
+ /// 1. `low > high`,
62
+ /// 2. `self.len() < low + 1`.
63
+ fn prop_sample ( self , size : Range < usize > ) -> Self :: Strategy ;
64
+ }
65
+
66
+ impl < T : Clone + fmt:: Debug > CollectionStrategy for Vec < T > {
67
+ type Strategy = SubseqStrategy < T > ;
68
+ type ValueTree = SubseqValueTree < T > ;
69
+ fn prop_sample ( self , size : Range < usize > ) -> Self :: Strategy {
70
+ SubseqStrategy :: new ( self , size)
71
+ }
72
+ }
73
+
74
+ /// A `Strategy` to generate subsequences, of a `Vec<T>`,
75
+ /// where the subsequences have a size: `min <= seq.len() < max`.
76
+ #[ derive( Debug , Clone ) ]
77
+ pub struct SubseqStrategy < T : Clone + fmt:: Debug > {
78
+ full : Vec < T > ,
79
+ size : Range < usize > ,
80
+ }
81
+
82
+ impl < T : Clone + fmt:: Debug > SubseqStrategy < T > {
83
+ /// Constructs a `SubseqStrategy` which will generate subsequences of
84
+ /// `source` where the subsequences have a size: `[size.start, size.end)`.
85
+ ///
86
+ /// # Safety
87
+ ///
88
+ /// A panic occurs when:
89
+ ///
90
+ /// 1. `size.start >= size.end`,
91
+ /// 2. `source.len() < size.start + 1`.
92
+ pub fn new ( source : Vec < T > , size : Range < usize > ) -> Self {
93
+ assert ! ( !( size. start >= size. end) ) ;
94
+ assert ! ( !( source. len( ) < size. start + 1 ) ) ;
95
+ Self {
96
+ full : source,
97
+ size : size,
98
+ }
99
+ }
100
+ }
101
+
102
+ impl < T : Clone + fmt:: Debug > Strategy for SubseqStrategy < T > {
103
+ type Value = SubseqValueTree < T > ;
104
+
105
+ fn new_value ( & self , runner : & mut TestRunner )
106
+ -> Result < Self :: Value , String >
107
+ {
108
+ // Generate the amount of elements in result:
109
+ let rng = runner. rng ( ) ;
110
+ let amount = rand:: distributions:: Range :: new (
111
+ self . size . start , self . size . end ) . ind_sample ( rng) ;
112
+
113
+ // Generate a subsequence of amount size.
114
+ let subvec = rand:: sample ( rng, self . full . iter ( ) . cloned ( ) , amount) ;
115
+
116
+ // We're done, yield the value tree.
117
+ Ok ( SubseqValueTree {
118
+ data : subvec,
119
+ len : amount,
120
+ min : self . size . start ,
121
+ } )
122
+ }
123
+ }
124
+
125
+ /// The `ValueTree` for `SubseqStrategy`.
126
+ pub struct SubseqValueTree < T : Clone + fmt:: Debug > {
127
+ data : Vec < T > ,
128
+ len : usize ,
129
+ min : usize
130
+ }
131
+
132
+ impl < T : Clone + fmt:: Debug > ValueTree for SubseqValueTree < T > {
133
+ type Value = Vec < T > ;
134
+
135
+ fn current ( & self ) -> Self :: Value {
136
+ // We verify manually that self.len <= self.data.len(),
137
+ // therefore it is safe. The assertion should always hold.
138
+ assert ! ( self . len <= self . data. len( ) ) ;
139
+ unsafe {
140
+ slice:: from_raw_parts ( self . data . as_ptr ( ) , self . len )
141
+ } . into ( )
142
+ }
143
+
144
+ fn simplify ( & mut self ) -> bool {
145
+ if self . len == self . min {
146
+ // We're not allowed to shrink further.
147
+ false
148
+ } else {
149
+ // Still possible to shrink. Do so by 1 element.
150
+ self . len -= 1 ;
151
+ true
152
+ }
153
+ }
154
+
155
+ fn complicate ( & mut self ) -> bool {
156
+ if self . len == self . data . len ( ) {
157
+ // We've reached the full subsequence, can't complicate more.
158
+ false
159
+ } else {
160
+ self . len += 1 ;
161
+ true
162
+ }
163
+ }
164
+ }
165
+
28
166
/// Strategy to create `Vec`s with a length in a certain range.
29
167
///
30
168
/// Created by the `vec()` function in the same module.
0 commit comments