Last active
January 5, 2023 16:38
Iterator::array_chunks for stable Rust 1.66
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub(crate) struct ChunksExact<const N: usize, I> { | |
iter: I, | |
} | |
impl<const N: usize, I: Iterator<Item = T>, T> Iterator for ChunksExact<N, I> { | |
type Item = [T; N]; | |
fn next(&mut self) -> Option<Self::Item> { | |
assert_ne!(N, 0); | |
let mut vec: Vec<T> = Vec::with_capacity(N); | |
for _ in 0..N { | |
match self.iter.next() { | |
Some(item) => vec.push(item), | |
None => return None, | |
} | |
} | |
let ary: [T; N] = vec.try_into().unwrap_or_else(|v: Vec<T>| { | |
panic!("Expected a Vec of length {} but it was {}", N, v.len()) | |
}); | |
Some(ary) | |
} | |
} | |
pub(crate) trait ChunksExactIterator: Sized { | |
/// Returns an iterator over `N` elements of the iterator at a time. | |
/// | |
/// This is a custom implementation of [Iterator::array_chunks] for stable | |
/// Rust 1.66, but for simplicity without | |
/// [`.into_remainder()`][std::iter::adapters::ArrayChunks]. | |
/// | |
/// # Panics | |
/// | |
/// Panics if `N` is 0. | |
/// | |
/// # Examples | |
/// | |
/// ``` | |
/// let mut iter = "lorem".chars().array_chunks(); | |
/// assert_eq!(iter.next(), Some(['l', 'o'])); | |
/// assert_eq!(iter.next(), Some(['r', 'e'])); | |
/// assert_eq!(iter.next(), None); | |
/// ``` | |
/// | |
/// TODO: Remove it after `iter_array_chunks` is stabilized. | |
/// https://github.com/rust-lang/rust/issues/100450 | |
fn chunks_exact<const N: usize>(self) -> ChunksExact<N, Self>; | |
} | |
impl<I: Iterator> ChunksExactIterator for I { | |
fn chunks_exact<const N: usize>(self) -> ChunksExact<N, Self> { | |
assert!(N != 0, "chunk size must be non-zero"); | |
ChunksExact { iter: self } | |
} | |
} | |
#[cfg(test)] | |
mod test { | |
use super::*; | |
#[test] | |
fn chunks_exact_with_divisible_input() { | |
let actual = ["a", "b", "c", "d"] | |
.into_iter() | |
.chunks_exact() | |
.collect::<Vec<[&str; 2]>>(); | |
assert_eq!(actual, vec![["a", "b"], ["c", "d"]]); | |
} | |
#[test] | |
fn chunks_exact_with_indivisible_input() { | |
let actual = ["a", "b", "c", "d"] | |
.into_iter() | |
.chunks_exact() | |
.collect::<Vec<[&str; 3]>>(); | |
assert_eq!(actual, vec![["a", "b", "c"]]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment