padded_iterator/lib.rs
1//! This crate provides an iterator that pads the end of the iterator with a value up to a given length.
2//!
3//! # Examples:
4//!
5//! ```
6//! use padded_iterator::PaddedIterBuilder;
7//!
8//! let mut iter = PaddedIterBuilder::new()
9//! .iter(vec![1, 2, 3].into_iter())
10//! .length(5)
11//! .pad(0)
12//! .build()
13//! .unwrap();
14//!
15//! assert_eq!(iter.next(), Some(1));
16//! assert_eq!(iter.next(), Some(2));
17//! assert_eq!(iter.next(), Some(3));
18//! assert_eq!(iter.next(), Some(0));
19//! assert_eq!(iter.next(), Some(0));
20//! assert_eq!(iter.next(), None);
21//! ```
22//!
23//! ```
24//! use padded_iterator::PaddedIter;
25//!
26//! let mut iter = PaddedIter::from((vec![1, 2, 3].into_iter(), 5, 0));
27//!
28//! assert_eq!(iter.next(), Some(1));
29//! assert_eq!(iter.next(), Some(2));
30//! assert_eq!(iter.next(), Some(3));
31//! assert_eq!(iter.next(), Some(0));
32//! assert_eq!(iter.next(), Some(0));
33//! assert_eq!(iter.next(), None);
34//! ```
35
36mod utils;
37#[cfg(test)]
38mod tests;
39
40pub use self::utils::BuildError;
41
42/// An iterator which has been padded to a given length.
43#[derive(Debug)]
44pub struct PaddedIter<T: Iterator<Item = U>, U> {
45 iter: T,
46 n: usize,
47 length: usize,
48 pad: U,
49}
50
51impl<T, U> PaddedIter<T, U>
52where
53 T: Iterator<Item = U>,
54 U: Clone,
55{
56 pub fn next(&mut self) -> Option<U> {
57 self.n += 1;
58
59 if self.n > self.length {
60 return None;
61 }
62
63 let next_item = self.iter.next();
64 match next_item {
65 Some(item) => Some(item),
66 None => Some(self.pad.clone()),
67 }
68 }
69}
70
71impl<T, U> From<(T, usize, U)> for PaddedIter<T, U>
72where
73 T: Iterator<Item = U>,
74 U: Clone,
75{
76 /// Create a new PaddedIter from an iterator, length, and pad value.
77 ///
78 /// # Examples:
79 ///
80 /// ```
81 /// use padded_iterator::PaddedIter;
82 ///
83 /// let mut iter = PaddedIter::from((vec![1, 2, 3].into_iter(), 5, 0));
84 ///
85 /// assert_eq!(iter.next(), Some(1));
86 /// assert_eq!(iter.next(), Some(2));
87 /// assert_eq!(iter.next(), Some(3));
88 /// assert_eq!(iter.next(), Some(0));
89 /// assert_eq!(iter.next(), Some(0));
90 /// assert_eq!(iter.next(), None);
91 /// ```
92 fn from((iter, length, pad): (T, usize, U)) -> Self {
93 Self {
94 iter,
95 n: 0,
96 length,
97 pad,
98 }
99 }
100}
101
102/// A builder for PaddedIter.
103pub struct PaddedIterBuilder<T: Iterator<Item = U>, U> {
104 iter: Option<T>,
105 length: Option<usize>,
106 pad: Option<U>,
107}
108
109impl<T, U> PaddedIterBuilder<T, U>
110where
111 T: Iterator<Item = U>,
112 U: Clone,
113{
114 pub fn new() -> Self {
115 PaddedIterBuilder {
116 iter: None,
117 length: None,
118 pad: None,
119 }
120 }
121
122 /// Sets the base iterator for the PaddedIter.
123 pub fn iter(mut self, iter: T) -> Self {
124 self.iter = Some(iter);
125 self
126 }
127
128 /// Sets the length to pad the iterator to.
129 pub fn length(mut self, length: usize) -> Self {
130 self.length = Some(length);
131 self
132 }
133
134 /// Sets the value to pad the iterator with.
135 pub fn pad(mut self, pad: U) -> Self {
136 self.pad = Some(pad);
137 self
138 }
139
140 /// Consumes the builder and returns a PaddedIter.
141 pub fn build(self) -> Result<PaddedIter<T, U>, BuildError> {
142 let iter = self.iter.ok_or(BuildError::IterNotSet)?;
143 let length = self.length.ok_or(BuildError::LengthNotSet)?;
144 let pad = self.pad.ok_or(BuildError::PadNotSet)?;
145
146 Ok(PaddedIter {
147 iter,
148 n: 0,
149 length,
150 pad,
151 })
152 }
153}