exhaust/impls/
core_primitive.rs1use core::{fmt, iter};
2
3use crate::iteration::{carry, peekable_exhaust};
4use crate::patterns::{
5 delegate_factory_and_iter, factory_is_self, impl_newtype_generic, impl_via_array,
6 impl_via_range,
7};
8use crate::Exhaust;
9
10impl Exhaust for () {
11 type Iter = iter::Once<()>;
12 fn exhaust_factories() -> Self::Iter {
13 iter::once(())
14 }
15 factory_is_self!();
16}
17
18impl_newtype_generic!(T: [], (T,), |x| (x,));
20
21exhaust_macros::impl_exhaust_for_tuples!(12);
24
25impl_via_array!(bool, [false, true]);
26
27impl_via_range!(char, '\x00', char::MAX);
28impl_via_range!(i8, i8::MIN, i8::MAX);
29impl_via_range!(u8, u8::MIN, u8::MAX);
30impl_via_range!(i16, i16::MIN, i16::MAX);
31impl_via_range!(u16, u16::MIN, u16::MAX);
32impl_via_range!(i32, i32::MIN, i32::MAX);
33impl_via_range!(u32, u32::MIN, u32::MAX);
34impl Exhaust for f32 {
37 delegate_factory_and_iter!(u32);
38
39 fn from_factory(factory: Self::Factory) -> Self {
40 f32::from_bits(factory)
41 }
42}
43
44impl<T: Exhaust, const N: usize> Exhaust for [T; N] {
45 type Iter = ExhaustArray<T, N>;
46 type Factory = [T::Factory; N];
47 fn exhaust_factories() -> Self::Iter {
48 ExhaustArray {
49 state: [(); N].map(|()| peekable_exhaust::<T>()),
50 done_zero: false,
51 }
52 }
53 fn from_factory(factory: Self::Factory) -> Self {
54 factory.map(T::from_factory)
55 }
56}
57
58pub struct ExhaustArray<T: Exhaust, const N: usize> {
60 state: [iter::Peekable<T::Iter>; N],
61 done_zero: bool,
62}
63
64impl<T, const N: usize> fmt::Debug for ExhaustArray<T, N>
65where
66 T: Exhaust<Iter: fmt::Debug, Factory: fmt::Debug>,
67{
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 f.debug_struct("ExhaustArray")
70 .field("state", &self.state)
71 .field("done_zero", &self.done_zero)
72 .finish()
73 }
74}
75
76impl<T: Exhaust, const N: usize> Clone for ExhaustArray<T, N> {
77 fn clone(&self) -> Self {
78 Self {
79 state: self.state.clone(),
80 done_zero: self.done_zero,
81 }
82 }
83}
84
85impl<T: Exhaust, const N: usize> Iterator for ExhaustArray<T, N> {
86 type Item = [T::Factory; N];
87
88 fn next(&mut self) -> Option<Self::Item> {
89 if N == 0 {
90 return if self.done_zero {
91 None
92 } else {
93 self.done_zero = true;
94 Some([(); N].map(|()| unreachable!()))
96 };
97 }
98
99 let has_next = self
101 .state
102 .iter_mut()
103 .all(|value_iter| value_iter.peek().is_some());
104
105 if !has_next {
106 return None;
107 }
108
109 let mut i = 0;
112 let item = [(); N].map(|()| {
113 let element = if i == N - 1 {
114 self.state[i].next().unwrap()
116 } else {
117 self.state[i].peek().unwrap().clone()
119 };
120 i += 1;
121 element
122 });
123
124 for i in (1..N).rev() {
128 let (high, low) = &mut self.state.split_at_mut(i);
129 if !carry(high.last_mut().unwrap(), &mut low[0], peekable_exhaust::<T>) {
130 break;
131 }
132 }
133
134 Some(item)
135 }
136}
137
138impl<T: Exhaust, const N: usize> iter::FusedIterator for ExhaustArray<T, N> {}