1 #![allow(unstable_name_collisions)] 2 3 use itertools::Itertools; 4 5 #[derive(Debug, Clone)] 6 #[must_use = "iterators are lazy and do nothing unless consumed"] 7 struct Panicking; 8 9 impl Iterator for Panicking { 10 type Item = u8; 11 next(&mut self) -> Option<u8>12 fn next(&mut self) -> Option<u8> { 13 panic!("iterator adaptor is not lazy") 14 } 15 size_hint(&self) -> (usize, Option<usize>)16 fn size_hint(&self) -> (usize, Option<usize>) { 17 (0, Some(0)) 18 } 19 } 20 21 impl ExactSizeIterator for Panicking {} 22 23 /// ## Usage example 24 /// ```compile_fail 25 /// must_use_tests! { 26 /// name { 27 /// Panicking.name(); // Add `let _ =` only if required (encountered error). 28 /// } 29 /// // ... 30 /// } 31 /// ``` 32 /// 33 /// **TODO:** test missing `must_use` attributes better, maybe with a new lint. 34 macro_rules! must_use_tests { 35 ($($(#[$attr:meta])* $name:ident $body:block)*) => { 36 $( 37 /// `#[deny(unused_must_use)]` should force us to ignore the resulting iterators 38 /// by adding `let _ = ...;` on every iterator. 39 /// If it does not, then a `must_use` attribute is missing on the associated struct. 40 /// 41 /// However, it's only helpful if we don't add `let _ =` before seeing if there is an error or not. 42 /// And it does not protect us against removed `must_use` attributes. 43 /// There is no simple way to test this yet. 44 #[deny(unused_must_use)] 45 #[test] 46 $(#[$attr])* 47 fn $name() $body 48 )* 49 }; 50 } 51 52 must_use_tests! { 53 // Itertools trait: 54 interleave { 55 let _ = Panicking.interleave(Panicking); 56 } 57 interleave_shortest { 58 let _ = Panicking.interleave_shortest(Panicking); 59 } 60 intersperse { 61 let _ = Panicking.intersperse(0); 62 } 63 intersperse_with { 64 let _ = Panicking.intersperse_with(|| 0); 65 } 66 get { 67 let _ = Panicking.get(1..4); 68 let _ = Panicking.get(1..=4); 69 let _ = Panicking.get(1..); 70 let _ = Panicking.get(..4); 71 let _ = Panicking.get(..=4); 72 let _ = Panicking.get(..); 73 } 74 zip_longest { 75 let _ = Panicking.zip_longest(Panicking); 76 } 77 zip_eq { 78 let _ = Panicking.zip_eq(Panicking); 79 } 80 batching { 81 let _ = Panicking.batching(Iterator::next); 82 } 83 chunk_by { 84 // ChunkBy 85 let _ = Panicking.chunk_by(|x| *x); 86 // Groups 87 let _ = Panicking.chunk_by(|x| *x).into_iter(); 88 } 89 chunks { 90 // IntoChunks 91 let _ = Panicking.chunks(1); 92 let _ = Panicking.chunks(2); 93 // Chunks 94 let _ = Panicking.chunks(1).into_iter(); 95 let _ = Panicking.chunks(2).into_iter(); 96 } 97 tuple_windows { 98 let _ = Panicking.tuple_windows::<(_,)>(); 99 let _ = Panicking.tuple_windows::<(_, _)>(); 100 let _ = Panicking.tuple_windows::<(_, _, _)>(); 101 } 102 circular_tuple_windows { 103 let _ = Panicking.circular_tuple_windows::<(_,)>(); 104 let _ = Panicking.circular_tuple_windows::<(_, _)>(); 105 let _ = Panicking.circular_tuple_windows::<(_, _, _)>(); 106 } 107 tuples { 108 let _ = Panicking.tuples::<(_,)>(); 109 let _ = Panicking.tuples::<(_, _)>(); 110 let _ = Panicking.tuples::<(_, _, _)>(); 111 } 112 tee { 113 let _ = Panicking.tee(); 114 } 115 map_into { 116 let _ = Panicking.map_into::<u16>(); 117 } 118 map_ok { 119 let _ = Panicking.map(Ok::<u8, ()>).map_ok(|x| x + 1); 120 } 121 filter_ok { 122 let _ = Panicking.map(Ok::<u8, ()>).filter_ok(|x| x % 2 == 0); 123 } 124 filter_map_ok { 125 let _ = Panicking.map(Ok::<u8, ()>).filter_map_ok(|x| { 126 if x % 2 == 0 { 127 Some(x + 1) 128 } else { 129 None 130 } 131 }); 132 } 133 flatten_ok { 134 let _ = Panicking.map(|x| Ok::<_, ()>([x])).flatten_ok(); 135 } 136 merge { 137 let _ = Panicking.merge(Panicking); 138 } 139 merge_by { 140 let _ = Panicking.merge_by(Panicking, |_, _| true); 141 } 142 merge_join_by { 143 let _ = Panicking.merge_join_by(Panicking, |_, _| true); 144 let _ = Panicking.merge_join_by(Panicking, Ord::cmp); 145 } 146 #[should_panic] 147 kmerge { 148 let _ = Panicking.map(|_| Panicking).kmerge(); 149 } 150 #[should_panic] 151 kmerge_by { 152 let _ = Panicking.map(|_| Panicking).kmerge_by(|_, _| true); 153 } 154 cartesian_product { 155 let _ = Panicking.cartesian_product(Panicking); 156 } 157 multi_cartesian_product { 158 let _ = vec![Panicking, Panicking, Panicking].into_iter().multi_cartesian_product(); 159 } 160 coalesce { 161 let _ = Panicking.coalesce(|x, y| if x == y { Ok(x) } else { Err((x, y)) }); 162 } 163 dedup { 164 let _ = Panicking.dedup(); 165 } 166 dedup_by { 167 let _ = Panicking.dedup_by(|_, _| true); 168 } 169 dedup_with_count { 170 let _ = Panicking.dedup_with_count(); 171 } 172 dedup_by_with_count { 173 let _ = Panicking.dedup_by_with_count(|_, _| true); 174 } 175 duplicates { 176 let _ = Panicking.duplicates(); 177 } 178 duplicates_by { 179 let _ = Panicking.duplicates_by(|x| *x); 180 } 181 unique { 182 let _ = Panicking.unique(); 183 } 184 unique_by { 185 let _ = Panicking.unique_by(|x| *x); 186 } 187 peeking_take_while { 188 let _ = Panicking.peekable().peeking_take_while(|x| x % 2 == 0); 189 } 190 take_while_ref { 191 let _ = Panicking.take_while_ref(|x| x % 2 == 0); 192 } 193 take_while_inclusive { 194 let _ = Panicking.take_while_inclusive(|x| x % 2 == 0); 195 } 196 while_some { 197 let _ = Panicking.map(Some).while_some(); 198 } 199 tuple_combinations1 { 200 let _ = Panicking.tuple_combinations::<(_,)>(); 201 } 202 #[should_panic] 203 tuple_combinations2 { 204 let _ = Panicking.tuple_combinations::<(_, _)>(); 205 } 206 #[should_panic] 207 tuple_combinations3 { 208 let _ = Panicking.tuple_combinations::<(_, _, _)>(); 209 } 210 combinations { 211 let _ = Panicking.combinations(0); 212 let _ = Panicking.combinations(1); 213 let _ = Panicking.combinations(2); 214 } 215 combinations_with_replacement { 216 let _ = Panicking.combinations_with_replacement(0); 217 let _ = Panicking.combinations_with_replacement(1); 218 let _ = Panicking.combinations_with_replacement(2); 219 } 220 permutations { 221 let _ = Panicking.permutations(0); 222 let _ = Panicking.permutations(1); 223 let _ = Panicking.permutations(2); 224 } 225 powerset { 226 let _ = Panicking.powerset(); 227 } 228 pad_using { 229 let _ = Panicking.pad_using(25, |_| 10); 230 } 231 with_position { 232 let _ = Panicking.with_position(); 233 } 234 positions { 235 let _ = Panicking.positions(|v| v % 2 == 0); 236 } 237 update { 238 let _ = Panicking.update(|n| *n += 1); 239 } 240 multipeek { 241 let _ = Panicking.multipeek(); 242 } 243 // Not iterator themselves but still lazy. 244 into_grouping_map { 245 let _ = Panicking.map(|x| (x, x + 1)).into_grouping_map(); 246 } 247 into_grouping_map_by { 248 let _ = Panicking.into_grouping_map_by(|x| *x); 249 } 250 // Macros: 251 iproduct { 252 let _ = itertools::iproduct!(Panicking); 253 let _ = itertools::iproduct!(Panicking, Panicking); 254 let _ = itertools::iproduct!(Panicking, Panicking, Panicking); 255 } 256 izip { 257 let _ = itertools::izip!(Panicking); 258 let _ = itertools::izip!(Panicking, Panicking); 259 let _ = itertools::izip!(Panicking, Panicking, Panicking); 260 } 261 chain { 262 let _ = itertools::chain!(Panicking); 263 let _ = itertools::chain!(Panicking, Panicking); 264 let _ = itertools::chain!(Panicking, Panicking, Panicking); 265 } 266 // Free functions: 267 multizip { 268 let _ = itertools::multizip((Panicking, Panicking)); 269 } 270 put_back { 271 let _ = itertools::put_back(Panicking); 272 let _ = itertools::put_back(Panicking).with_value(15); 273 } 274 peek_nth { 275 let _ = itertools::peek_nth(Panicking); 276 } 277 put_back_n { 278 let _ = itertools::put_back_n(Panicking); 279 } 280 rciter { 281 let _ = itertools::rciter(Panicking); 282 } 283 } 284