diff --git a/Cargo.toml b/Cargo.toml index 6ec88a9e9..84e497153 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ description = "Extra iterator adaptors, iterator methods, free functions, and ma keywords = ["iterator", "data-structure", "zip", "product"] categories = ["algorithms", "rust-patterns", "no-std", "no-std::no-alloc"] -edition = "2018" +edition = "2021" # When bumping, please resolve all `#[allow(clippy::*)]` that are newly resolvable. rust-version = "1.63.0" @@ -30,7 +30,7 @@ rand = "0.7" criterion = { version = "0.4.0", features = ["html_reports"] } paste = "1.0.0" # Used in test_std to instantiate generic tests permutohedron = "0.2" -quickcheck = { version = "0.9", default_features = false } +quickcheck = { version = "0.9", default-features = false } [features] default = ["use_std"] diff --git a/benches/powerset.rs b/benches/powerset.rs index 018333d31..7d7fc17fe 100644 --- a/benches/powerset.rs +++ b/benches/powerset.rs @@ -8,7 +8,7 @@ const fn calc_iters(n: usize) -> usize { } fn powerset_n(c: &mut Criterion, n: usize) { - let id = format!("powerset {}", n); + let id = format!("powerset {n}"); c.bench_function(id.as_str(), move |b| { b.iter(|| { for _ in 0..calc_iters(n) { @@ -21,7 +21,7 @@ fn powerset_n(c: &mut Criterion, n: usize) { } fn powerset_n_fold(c: &mut Criterion, n: usize) { - let id = format!("powerset {} fold", n); + let id = format!("powerset {n} fold"); c.bench_function(id.as_str(), move |b| { b.iter(|| { for _ in 0..calc_iters(n) { diff --git a/benches/specializations.rs b/benches/specializations.rs index e70323f8e..6f753e75c 100644 --- a/benches/specializations.rs +++ b/benches/specializations.rs @@ -654,7 +654,7 @@ bench_specializations! { .map(|x| if x % 2 == 1 { Err(x) } else { Ok(x) }) .collect_vec()); } - v.iter().copied().filter_map_ok(|x| if x % 3 == 0 { Some(x + 1) } else { None }) + v.iter().copied().filter_map_ok(|x| (x % 3 == 0).then_some(x + 1)) } flatten_ok { DoubleEndedIterator diff --git a/examples/iris.rs b/examples/iris.rs index 63f9c4832..fe783b9b7 100644 --- a/examples/iris.rs +++ b/examples/iris.rs @@ -65,7 +65,7 @@ fn main() { }); let mut irises = match irises { Err(e) => { - println!("Error parsing: {:?}", e); + println!("Error parsing: {e:?}"); std::process::exit(1); } Ok(data) => data, @@ -101,7 +101,7 @@ fn main() { // using Itertools::tuple_combinations for (a, b) in (0..4).tuple_combinations() { - println!("Column {} vs {}:", a, b); + println!("Column {a} vs {b}:"); // Clear plot // diff --git a/src/adaptors/mod.rs b/src/adaptors/mod.rs index d717e5408..dc6736e31 100644 --- a/src/adaptors/mod.rs +++ b/src/adaptors/mod.rs @@ -16,6 +16,7 @@ use crate::size_hint::{self, SizeHint}; use std::fmt; use std::iter::{Enumerate, FromIterator, Fuse, FusedIterator}; use std::marker::PhantomData; +use std::ops::ControlFlow; /// An iterator adaptor that alternates elements from two iterators until both /// run out. @@ -93,13 +94,13 @@ where let res = i.try_fold(init, |mut acc, x| { acc = f(acc, x); match j.next() { - Some(y) => Ok(f(acc, y)), - None => Err(acc), + Some(y) => ControlFlow::Continue(f(acc, y)), + None => ControlFlow::Break(acc), } }); match res { - Ok(acc) => j.fold(acc, f), - Err(acc) => i.fold(acc, f), + ControlFlow::Continue(acc) => j.fold(acc, f), + ControlFlow::Break(acc) => i.fold(acc, f), } } } @@ -216,14 +217,12 @@ where let res = i.try_fold(init, |mut acc, x| { acc = f(acc, x); match j.next() { - Some(y) => Ok(f(acc, y)), - None => Err(acc), + Some(y) => ControlFlow::Continue(f(acc, y)), + None => ControlFlow::Break(acc), } }); - match res { - Ok(val) => val, - Err(val) => val, - } + let (ControlFlow::Continue(val) | ControlFlow::Break(val)) = res; + val } } @@ -595,14 +594,11 @@ where F: FnMut(B, Self::Item) -> B, { let res = self.iter.try_fold(acc, |acc, item| match item { - Some(item) => Ok(f(acc, item)), - None => Err(acc), + Some(item) => ControlFlow::Continue(f(acc, item)), + None => ControlFlow::Break(acc), }); - - match res { - Ok(val) => val, - Err(val) => val, - } + let (ControlFlow::Continue(val) | ControlFlow::Break(val)) = res; + val } } diff --git a/src/lib.rs b/src/lib.rs index 0f5ea8ee2..f4799f4ba 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,7 +49,9 @@ //! //! ## Rust Version //! -//! This version of itertools requires Rust 1.63.0 or later. +//! This version of itertools requires Rust +#![doc = env!("CARGO_PKG_RUST_VERSION")] +//! or later. #[cfg(not(feature = "use_std"))] extern crate core as std; @@ -2318,10 +2320,10 @@ pub trait Itertools: Iterator { // estimate lower bound of capacity needed let (lower, _) = self.size_hint(); let mut result = String::with_capacity(sep.len() * lower); - write!(&mut result, "{}", first_elt).unwrap(); + write!(&mut result, "{first_elt}").unwrap(); self.for_each(|elt| { result.push_str(sep); - write!(&mut result, "{}", elt).unwrap(); + write!(&mut result, "{elt}").unwrap(); }); result } @@ -2712,7 +2714,7 @@ pub trait Itertools: Iterator { Self: Sized, F: FnMut(B, Self::Item) -> FoldWhile, { - use Result::{Err as Break, Ok as Continue}; + use std::ops::ControlFlow::{Break, Continue}; let result = self.try_fold( init, @@ -4520,13 +4522,7 @@ where (Some(a), Some(b)) => a == b, _ => false, }; - assert!( - equal, - "Failed assertion {a:?} == {b:?} for iteration {i}", - i = i, - a = a, - b = b - ); + assert!(equal, "Failed assertion {a:?} == {b:?} for iteration {i}"); i += 1; } } diff --git a/src/process_results_impl.rs b/src/process_results_impl.rs index ad6c60d3c..fea93ab1f 100644 --- a/src/process_results_impl.rs +++ b/src/process_results_impl.rs @@ -62,8 +62,7 @@ where impl<'a, I, T, E> DoubleEndedIterator for ProcessResults<'a, I, E> where - I: Iterator>, - I: DoubleEndedIterator, + I: DoubleEndedIterator>, { fn next_back(&mut self) -> Option { let item = self.iter.next_back(); diff --git a/src/repeatn.rs b/src/repeatn.rs index d86ad9fac..a30f2b4ed 100644 --- a/src/repeatn.rs +++ b/src/repeatn.rs @@ -34,7 +34,7 @@ where fn next(&mut self) -> Option { if self.n > 1 { self.n -= 1; - self.elt.as_ref().cloned() + self.elt.clone() } else { self.n = 0; self.elt.take() diff --git a/src/zip_longest.rs b/src/zip_longest.rs index d4eb9a882..8b3a47c46 100644 --- a/src/zip_longest.rs +++ b/src/zip_longest.rs @@ -1,6 +1,7 @@ use super::size_hint; use std::cmp::Ordering::{Equal, Greater, Less}; use std::iter::{Fuse, FusedIterator}; +use std::ops::ControlFlow; use crate::either_or_both::EitherOrBoth; @@ -62,12 +63,12 @@ where { let Self { mut a, mut b } = self; let res = a.try_fold(init, |init, a| match b.next() { - Some(b) => Ok(f(init, EitherOrBoth::Both(a, b))), - None => Err(f(init, EitherOrBoth::Left(a))), + Some(b) => ControlFlow::Continue(f(init, EitherOrBoth::Both(a, b))), + None => ControlFlow::Break(f(init, EitherOrBoth::Left(a))), }); match res { - Ok(acc) => b.map(EitherOrBoth::Right).fold(acc, f), - Err(acc) => a.map(EitherOrBoth::Left).fold(acc, f), + ControlFlow::Continue(acc) => b.map(EitherOrBoth::Right).fold(acc, f), + ControlFlow::Break(acc) => a.map(EitherOrBoth::Left).fold(acc, f), } } } diff --git a/tests/laziness.rs b/tests/laziness.rs index c559d33ad..9d52eee1a 100644 --- a/tests/laziness.rs +++ b/tests/laziness.rs @@ -122,13 +122,7 @@ must_use_tests! { let _ = Panicking.map(Ok::).filter_ok(|x| x % 2 == 0); } filter_map_ok { - let _ = Panicking.map(Ok::).filter_map_ok(|x| { - if x % 2 == 0 { - Some(x + 1) - } else { - None - } - }); + let _ = Panicking.map(Ok::).filter_map_ok(|x| (x % 2 == 0).then_some(x + 1)); } flatten_ok { let _ = Panicking.map(|x| Ok::<_, ()>([x])).flatten_ok(); diff --git a/tests/quick.rs b/tests/quick.rs index 672901e7c..4bd4e53db 100644 --- a/tests/quick.rs +++ b/tests/quick.rs @@ -275,8 +275,7 @@ where let actual_count = total_actual_count - i; if actual_count != returned_count { println!( - "Total iterations: {} True count: {} returned count: {}", - i, actual_count, returned_count + "Total iterations: {i} True count: {actual_count} returned count: {returned_count}" ); return false; @@ -676,7 +675,7 @@ quickcheck! { assert_eq!(perm.len(), k); let all_items_valid = perm.iter().all(|p| vals.contains(p)); - assert!(all_items_valid, "perm contains value not from input: {:?}", perm); + assert!(all_items_valid, "perm contains value not from input: {perm:?}"); // Check that all perm items are distinct let distinct_len = { @@ -686,7 +685,7 @@ quickcheck! { assert_eq!(perm.len(), distinct_len); // Check that the perm is new - assert!(actual.insert(perm.clone()), "perm already encountered: {:?}", perm); + assert!(actual.insert(perm.clone()), "perm already encountered: {perm:?}"); } } @@ -712,8 +711,7 @@ quickcheck! { for next_perm in perms { assert!( next_perm > curr_perm, - "next perm isn't greater-than current; next_perm={:?} curr_perm={:?} n={}", - next_perm, curr_perm, n + "next perm isn't greater-than current; next_perm={next_perm:?} curr_perm={curr_perm:?} n={n}" ); curr_perm = next_perm; @@ -1874,7 +1872,7 @@ quickcheck! { fn fused_filter_map_ok(a: Iter) -> bool { is_fused(a.map(|x| if x % 2 == 0 {Ok(x)} else {Err(x)} ) - .filter_map_ok(|x| if x % 3 == 0 {Some(x / 3)} else {None}) + .filter_map_ok(|x| (x % 3 == 0).then_some(x / 3)) .fuse()) } diff --git a/tests/specializations.rs b/tests/specializations.rs index 3e4831024..8895d8da1 100644 --- a/tests/specializations.rs +++ b/tests/specializations.rs @@ -43,7 +43,7 @@ where I: Iterator + Clone, { macro_rules! check_specialized { - ($src:expr, |$it:pat| $closure:expr) => { + ($src:expr, |$it:pat_param| $closure:expr) => { // Many iterators special-case the first elements, so we test specializations for iterators that have already been advanced. let mut src = $src.clone(); for _ in 0..5 { @@ -101,7 +101,7 @@ where I: DoubleEndedIterator + Clone, { macro_rules! check_specialized { - ($src:expr, |$it:pat| $closure:expr) => { + ($src:expr, |$it:pat_param| $closure:expr) => { // Many iterators special-case the first elements, so we test specializations for iterators that have already been advanced. let mut src = $src.clone(); for step in 0..8 { @@ -229,7 +229,7 @@ quickcheck! { } fn while_some(v: Vec) -> () { - test_specializations(&v.iter().map(|&x| if x < 100 { Some(2 * x) } else { None }).while_some()); + test_specializations(&v.iter().map(|&x| (x < 100).then_some(2 * x)).while_some()); } fn pad_using(v: Vec) -> () { @@ -460,7 +460,7 @@ quickcheck! { } fn filter_map_ok(v: Vec>) -> () { - let it = v.into_iter().filter_map_ok(|i| if i < 20 { Some(i * 2) } else { None }); + let it = v.into_iter().filter_map_ok(|i| (i < 20).then_some(i * 2)); test_specializations(&it); test_double_ended_specializations(&it); } @@ -481,7 +481,7 @@ quickcheck! { fn helper(it: impl DoubleEndedIterator> + Clone) { macro_rules! check_results_specialized { - ($src:expr, |$it:pat| $closure:expr) => { + ($src:expr, |$it:pat_param| $closure:expr) => { assert_eq!( itertools::process_results($src.clone(), |$it| $closure), itertools::process_results($src.clone(), |i| { diff --git a/tests/test_std.rs b/tests/test_std.rs index ad391faad..f7d38b20b 100644 --- a/tests/test_std.rs +++ b/tests/test_std.rs @@ -1453,9 +1453,7 @@ fn format() { #[test] fn while_some() { - let ns = (1..10) - .map(|x| if x % 5 != 0 { Some(x) } else { None }) - .while_some(); + let ns = (1..10).map(|x| (x % 5 != 0).then_some(x)).while_some(); it::assert_equal(ns, vec![1, 2, 3, 4]); } @@ -1507,7 +1505,7 @@ fn tree_reduce() { Some(s.to_string()) }; let num_strings = (0..i).map(|x| x.to_string()); - let actual = num_strings.tree_reduce(|a, b| format!("{} {} x", a, b)); + let actual = num_strings.tree_reduce(|a, b| format!("{a} {b} x")); assert_eq!(actual, expected); } }