input_linux/
enum_iterator.rs

1//! Iteration over enum values.
2
3use std::marker::PhantomData;
4
5/// Allows [`EnumIterator`] to iterate over an enum type.
6pub trait IterableEnum: Sized {
7    /// Given an index into the iterator, return the value and the next index.
8    ///
9    /// Iterators shall start by calling this with `0`.
10    fn iter_next(v: usize) -> Option<(usize, Self)>;
11
12    /// Instantiates an [`EnumIterator`] for an iterable type.
13    fn iter() -> EnumIterator<Self>;
14}
15
16impl IterableEnum for u16 {
17    fn iter_next(v: usize) -> Option<(usize, Self)> {
18        if v < 0xffff {
19            Some((v + 1, v as u16))
20        } else {
21            None
22        }
23    }
24
25    fn iter() -> EnumIterator<Self> {
26        EnumIterator::new(0)
27    }
28}
29
30/// Iterates over all values of an enum.
31#[derive(Copy, Clone, Debug)]
32pub struct EnumIterator<T> {
33    count: usize,
34    _marker: PhantomData<fn() -> T>,
35}
36
37impl<T: IterableEnum> EnumIterator<T> {
38    pub(crate) fn new(start: usize) -> Self {
39        EnumIterator {
40            count: start,
41            _marker: PhantomData,
42        }
43    }
44}
45
46impl<T: IterableEnum> Iterator for EnumIterator<T> {
47    type Item = T;
48
49    fn next(&mut self) -> Option<Self::Item> {
50        match T::iter_next(self.count) {
51            Some((new_count, res)) => {
52                self.count = new_count;
53                Some(res)
54            },
55            None => None,
56        }
57    }
58}