283 lines
7.9 KiB
Rust
283 lines
7.9 KiB
Rust
#![allow(unstable_name_collisions)]
|
|
|
|
use itertools::Itertools;
|
|
|
|
#[derive(Debug, Clone)]
|
|
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
|
struct Panicking;
|
|
|
|
impl Iterator for Panicking {
|
|
type Item = u8;
|
|
|
|
fn next(&mut self) -> Option<u8> {
|
|
panic!("iterator adaptor is not lazy")
|
|
}
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
(0, Some(0))
|
|
}
|
|
}
|
|
|
|
impl ExactSizeIterator for Panicking {}
|
|
|
|
/// ## Usage example
|
|
/// ```compile_fail
|
|
/// must_use_tests! {
|
|
/// name {
|
|
/// Panicking.name(); // Add `let _ =` only if required (encountered error).
|
|
/// }
|
|
/// // ...
|
|
/// }
|
|
/// ```
|
|
///
|
|
/// **TODO:** test missing `must_use` attributes better, maybe with a new lint.
|
|
macro_rules! must_use_tests {
|
|
($($(#[$attr:meta])* $name:ident $body:block)*) => {
|
|
$(
|
|
/// `#[deny(unused_must_use)]` should force us to ignore the resulting iterators
|
|
/// by adding `let _ = ...;` on every iterator.
|
|
/// If it does not, then a `must_use` attribute is missing on the associated struct.
|
|
///
|
|
/// However, it's only helpful if we don't add `let _ =` before seeing if there is an error or not.
|
|
/// And it does not protect us against removed `must_use` attributes.
|
|
/// There is no simple way to test this yet.
|
|
#[deny(unused_must_use)]
|
|
#[test]
|
|
$(#[$attr])*
|
|
fn $name() $body
|
|
)*
|
|
};
|
|
}
|
|
|
|
must_use_tests! {
|
|
// Itertools trait:
|
|
interleave {
|
|
let _ = Panicking.interleave(Panicking);
|
|
}
|
|
interleave_shortest {
|
|
let _ = Panicking.interleave_shortest(Panicking);
|
|
}
|
|
intersperse {
|
|
let _ = Panicking.intersperse(0);
|
|
}
|
|
intersperse_with {
|
|
let _ = Panicking.intersperse_with(|| 0);
|
|
}
|
|
get {
|
|
let _ = Panicking.get(1..4);
|
|
let _ = Panicking.get(1..=4);
|
|
let _ = Panicking.get(1..);
|
|
let _ = Panicking.get(..4);
|
|
let _ = Panicking.get(..=4);
|
|
let _ = Panicking.get(..);
|
|
}
|
|
zip_longest {
|
|
let _ = Panicking.zip_longest(Panicking);
|
|
}
|
|
zip_eq {
|
|
let _ = Panicking.zip_eq(Panicking);
|
|
}
|
|
batching {
|
|
let _ = Panicking.batching(Iterator::next);
|
|
}
|
|
chunk_by {
|
|
// ChunkBy
|
|
let _ = Panicking.chunk_by(|x| *x);
|
|
// Groups
|
|
let _ = Panicking.chunk_by(|x| *x).into_iter();
|
|
}
|
|
chunks {
|
|
// IntoChunks
|
|
let _ = Panicking.chunks(1);
|
|
let _ = Panicking.chunks(2);
|
|
// Chunks
|
|
let _ = Panicking.chunks(1).into_iter();
|
|
let _ = Panicking.chunks(2).into_iter();
|
|
}
|
|
tuple_windows {
|
|
let _ = Panicking.tuple_windows::<(_,)>();
|
|
let _ = Panicking.tuple_windows::<(_, _)>();
|
|
let _ = Panicking.tuple_windows::<(_, _, _)>();
|
|
}
|
|
circular_tuple_windows {
|
|
let _ = Panicking.circular_tuple_windows::<(_,)>();
|
|
let _ = Panicking.circular_tuple_windows::<(_, _)>();
|
|
let _ = Panicking.circular_tuple_windows::<(_, _, _)>();
|
|
}
|
|
tuples {
|
|
let _ = Panicking.tuples::<(_,)>();
|
|
let _ = Panicking.tuples::<(_, _)>();
|
|
let _ = Panicking.tuples::<(_, _, _)>();
|
|
}
|
|
tee {
|
|
let _ = Panicking.tee();
|
|
}
|
|
map_into {
|
|
let _ = Panicking.map_into::<u16>();
|
|
}
|
|
map_ok {
|
|
let _ = Panicking.map(Ok::<u8, ()>).map_ok(|x| x + 1);
|
|
}
|
|
filter_ok {
|
|
let _ = Panicking.map(Ok::<u8, ()>).filter_ok(|x| x % 2 == 0);
|
|
}
|
|
filter_map_ok {
|
|
let _ = Panicking.map(Ok::<u8, ()>).filter_map_ok(|x| {
|
|
if x % 2 == 0 {
|
|
Some(x + 1)
|
|
} else {
|
|
None
|
|
}
|
|
});
|
|
}
|
|
flatten_ok {
|
|
let _ = Panicking.map(|x| Ok::<_, ()>([x])).flatten_ok();
|
|
}
|
|
merge {
|
|
let _ = Panicking.merge(Panicking);
|
|
}
|
|
merge_by {
|
|
let _ = Panicking.merge_by(Panicking, |_, _| true);
|
|
}
|
|
merge_join_by {
|
|
let _ = Panicking.merge_join_by(Panicking, |_, _| true);
|
|
let _ = Panicking.merge_join_by(Panicking, Ord::cmp);
|
|
}
|
|
#[should_panic]
|
|
kmerge {
|
|
let _ = Panicking.map(|_| Panicking).kmerge();
|
|
}
|
|
#[should_panic]
|
|
kmerge_by {
|
|
let _ = Panicking.map(|_| Panicking).kmerge_by(|_, _| true);
|
|
}
|
|
cartesian_product {
|
|
let _ = Panicking.cartesian_product(Panicking);
|
|
}
|
|
multi_cartesian_product {
|
|
let _ = vec![Panicking, Panicking, Panicking].into_iter().multi_cartesian_product();
|
|
}
|
|
coalesce {
|
|
let _ = Panicking.coalesce(|x, y| if x == y { Ok(x) } else { Err((x, y)) });
|
|
}
|
|
dedup {
|
|
let _ = Panicking.dedup();
|
|
}
|
|
dedup_by {
|
|
let _ = Panicking.dedup_by(|_, _| true);
|
|
}
|
|
dedup_with_count {
|
|
let _ = Panicking.dedup_with_count();
|
|
}
|
|
dedup_by_with_count {
|
|
let _ = Panicking.dedup_by_with_count(|_, _| true);
|
|
}
|
|
duplicates {
|
|
let _ = Panicking.duplicates();
|
|
}
|
|
duplicates_by {
|
|
let _ = Panicking.duplicates_by(|x| *x);
|
|
}
|
|
unique {
|
|
let _ = Panicking.unique();
|
|
}
|
|
unique_by {
|
|
let _ = Panicking.unique_by(|x| *x);
|
|
}
|
|
peeking_take_while {
|
|
let _ = Panicking.peekable().peeking_take_while(|x| x % 2 == 0);
|
|
}
|
|
take_while_ref {
|
|
let _ = Panicking.take_while_ref(|x| x % 2 == 0);
|
|
}
|
|
take_while_inclusive {
|
|
let _ = Panicking.take_while_inclusive(|x| x % 2 == 0);
|
|
}
|
|
while_some {
|
|
let _ = Panicking.map(Some).while_some();
|
|
}
|
|
tuple_combinations1 {
|
|
let _ = Panicking.tuple_combinations::<(_,)>();
|
|
}
|
|
#[should_panic]
|
|
tuple_combinations2 {
|
|
let _ = Panicking.tuple_combinations::<(_, _)>();
|
|
}
|
|
#[should_panic]
|
|
tuple_combinations3 {
|
|
let _ = Panicking.tuple_combinations::<(_, _, _)>();
|
|
}
|
|
combinations {
|
|
let _ = Panicking.combinations(0);
|
|
let _ = Panicking.combinations(1);
|
|
let _ = Panicking.combinations(2);
|
|
}
|
|
combinations_with_replacement {
|
|
let _ = Panicking.combinations_with_replacement(0);
|
|
let _ = Panicking.combinations_with_replacement(1);
|
|
let _ = Panicking.combinations_with_replacement(2);
|
|
}
|
|
permutations {
|
|
let _ = Panicking.permutations(0);
|
|
let _ = Panicking.permutations(1);
|
|
let _ = Panicking.permutations(2);
|
|
}
|
|
powerset {
|
|
let _ = Panicking.powerset();
|
|
}
|
|
pad_using {
|
|
let _ = Panicking.pad_using(25, |_| 10);
|
|
}
|
|
with_position {
|
|
let _ = Panicking.with_position();
|
|
}
|
|
positions {
|
|
let _ = Panicking.positions(|v| v % 2 == 0);
|
|
}
|
|
update {
|
|
let _ = Panicking.update(|n| *n += 1);
|
|
}
|
|
multipeek {
|
|
let _ = Panicking.multipeek();
|
|
}
|
|
// Not iterator themselves but still lazy.
|
|
into_grouping_map {
|
|
let _ = Panicking.map(|x| (x, x + 1)).into_grouping_map();
|
|
}
|
|
into_grouping_map_by {
|
|
let _ = Panicking.into_grouping_map_by(|x| *x);
|
|
}
|
|
// Macros:
|
|
iproduct {
|
|
let _ = itertools::iproduct!(Panicking);
|
|
let _ = itertools::iproduct!(Panicking, Panicking);
|
|
let _ = itertools::iproduct!(Panicking, Panicking, Panicking);
|
|
}
|
|
izip {
|
|
let _ = itertools::izip!(Panicking);
|
|
let _ = itertools::izip!(Panicking, Panicking);
|
|
let _ = itertools::izip!(Panicking, Panicking, Panicking);
|
|
}
|
|
chain {
|
|
let _ = itertools::chain!(Panicking);
|
|
let _ = itertools::chain!(Panicking, Panicking);
|
|
let _ = itertools::chain!(Panicking, Panicking, Panicking);
|
|
}
|
|
// Free functions:
|
|
multizip {
|
|
let _ = itertools::multizip((Panicking, Panicking));
|
|
}
|
|
put_back {
|
|
let _ = itertools::put_back(Panicking);
|
|
let _ = itertools::put_back(Panicking).with_value(15);
|
|
}
|
|
peek_nth {
|
|
let _ = itertools::peek_nth(Panicking);
|
|
}
|
|
put_back_n {
|
|
let _ = itertools::put_back_n(Panicking);
|
|
}
|
|
rciter {
|
|
let _ = itertools::rciter(Panicking);
|
|
}
|
|
}
|