1use crate::seq_num::SeqNum;
2use std::iter::Iterator;
3
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6
7#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
48#[derive(Clone, Default, Debug)]
49pub struct Sequence<T>
50where
51 T: SeqNum,
52{
53 next: T,
54 incr: T,
56 #[cfg_attr(feature = "serde", serde(default = "SeqNum::max_val"))]
57 max: T,
58}
59
60impl<T> Sequence<T>
61where
62 T: SeqNum,
63{
64 #[must_use]
66 pub fn new() -> Self {
67 Self {
68 next: T::zero(),
69 incr: T::one(),
70 max: T::max_val(),
71 }
72 }
73
74 #[must_use]
76 fn dead() -> Self {
77 Self {
78 next: T::zero(),
79 incr: T::zero(),
80 max: T::max_val(),
81 }
82 }
83
84 #[must_use]
86 pub fn start_with(val: T) -> Self {
87 Self {
88 next: val,
89 incr: T::one(),
90 max: T::max_val(),
91 }
92 }
93
94 #[must_use]
96 pub fn start_after(val: T) -> Self {
97 match val.checked_add(T::one()) {
98 Some(next) => Self {
99 next,
100 incr: T::one(),
101 max: T::max_val(),
102 },
103 None => Self::dead(),
104 }
105 }
106
107 pub fn start_after_highest(values: &mut dyn Iterator<Item = &T>) -> Self {
109 Self::start_after(
110 *values
111 .reduce(|x, y| std::cmp::max(x, y))
112 .unwrap_or(&T::zero()),
113 )
114 }
115
116 pub fn with_start_end_increment(start: T, end: T, incr: T) -> Self {
118 Self {
119 next: start,
120 incr,
121 max: end,
122 }
123 }
124
125 #[must_use]
142 pub fn with_increment(mut self, incr: T) -> Self {
143 if self.is_active() {
144 self.incr = incr;
145 }
146 self
147 }
148
149 pub fn continue_after(&mut self, val: T) {
152 match val.checked_add(self.incr) {
153 Some(candidate) => {
154 self.next = std::cmp::max(self.next, candidate);
155 }
156 None => {
157 self.set_passive();
158 }
159 }
160 }
161
162 pub fn peek(&self) -> Option<T> {
165 if self.is_passive() {
166 None
167 } else {
168 Some(self.next)
169 }
170 }
171
172 fn set_passive(&mut self) {
173 self.incr = T::zero();
174 }
175 fn is_active(&self) -> bool {
176 self.incr != T::zero()
177 }
178 fn is_passive(&self) -> bool {
179 self.incr == T::zero()
180 }
181}
182
183impl<T> Iterator for Sequence<T>
192where
193 T: SeqNum,
194{
195 type Item = T;
196
197 fn next(&mut self) -> Option<Self::Item> {
198 if self.is_passive() {
199 None
200 } else {
201 let current = self.next;
202 match self.next.checked_add(self.incr) {
203 Some(next) => {
204 if next > self.max {
205 self.set_passive();
206 } else {
207 self.next = next;
208 }
209 }
210 None => {
211 self.set_passive();
212 }
213 }
214 Some(current)
215 }
216 }
217}
218
219#[cfg(test)]
220mod test {
221 use super::Sequence;
222
223 #[test]
224 fn test_sequence() {
225 let mut sequence = Sequence::<usize>::new();
226 assert_eq!(sequence.next(), Some(0_usize));
227 assert_eq!(sequence.next(), Some(1_usize));
228
229 sequence.continue_after(5);
230 assert_eq!(sequence.next(), Some(6));
231
232 sequence.continue_after(15);
233 sequence.continue_after(7);
234 sequence.continue_after(0);
235 assert_eq!(sequence.next(), Some(16));
236 assert_eq!(sequence.peek(), Some(17));
237 assert_eq!(sequence.peek(), Some(17));
238 assert_eq!(sequence.next(), Some(17));
239 }
240
241 #[test]
242 fn test_increment() {
243 let mut sequence = Sequence::<u8>::new().with_increment(5);
244 assert_eq!(sequence.next(), Some(0));
245 assert_eq!(sequence.next(), Some(5));
246 assert_eq!(sequence.next(), Some(10));
247
248 sequence.continue_after(152);
249 assert_eq!(sequence.next(), Some(157));
250 assert_eq!(sequence.next(), Some(162));
251
252 sequence.continue_after(251);
253 assert_eq!(sequence.next(), None);
254 }
255
256 #[test]
257 fn test_exhaust() {
258 let mut sequence = Sequence::<u64>::new();
259 sequence.continue_after(u64::MAX - 2);
260 assert!(sequence.is_active());
261 assert!(sequence.next().is_some());
262
263 assert!(sequence.peek().is_some());
264 assert!(sequence.peek().is_some());
265 assert!(sequence.next().is_some());
266
267 assert!(sequence.peek().is_none());
268 assert!(sequence.next().is_none());
269 }
270
271 #[cfg(feature = "serde")]
272 #[test]
273 fn test_serde() {
274 let mut sequence = Sequence::<u32>::with_start_end_increment(22, 99, 11);
275 assert_eq!(sequence.next(), Some(22));
276 let s = serde_json::to_string(&sequence).unwrap();
277 assert_eq!(&*s, r#"{"next":33,"incr":11,"max":99}"#);
278
279 let mut sequence2: Sequence<u32> = serde_json::from_str(&*s).unwrap();
280 assert_eq!(sequence2.next(), Some(33));
281 assert_eq!(sequence2.next(), Some(44));
282 assert_eq!(sequence2.next(), Some(55));
283 assert_eq!(sequence2.next(), Some(66));
284 assert_eq!(sequence2.next(), Some(77));
285 assert_eq!(sequence2.next(), Some(88));
286 assert_eq!(sequence2.next(), Some(99));
287 assert_eq!(sequence2.next(), None);
288
289 let old_format = r#"{"next":88,"incr":11}"#;
291 let mut sequence3: Sequence<u32> = serde_json::from_str(&old_format).unwrap();
292 assert_eq!(sequence3.next(), Some(88));
293 assert_eq!(sequence3.next(), Some(99));
294 assert_eq!(sequence3.next(), Some(110));
295 assert_eq!(sequence3.next(), Some(121));
296 }
297
298 #[test]
299 fn test_iter() {
300 assert_eq!(
301 Sequence::<u8>::with_start_end_increment(23, 38, 3).sum::<u8>(),
302 183
303 );
304 }
305}