1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
//! This crate provides the [`Exhaust`] trait and derive macro, which allow iterating over
//! all values of a given type.
//!
//! # Package features
//!
//! All features are enabled by default.
//! If you set `default-features = false`, `exhaust` becomes `no_std` compatible.
//! The `alloc` and `std` features add `Exhaust` implementations for
//! the corresponding standard library crates.
extern crate alloc;
extern crate std;
pub use Exhaust;
pub
/// Reexport for compatibility with v0.1.0;
/// new code should use [`impls::ExhaustArray`].
pub use ExhaustArray;
pub use *;
/// Types that can be exhaustively iterated. That is, an iterator is available which
/// produces every possible value of this type.
///
/// When implementing this trait, take note of
/// [the requirements noted below in `exhaust()`](Self::exhaust) for a correct implementation.
///
/// Implementors must also implement [`Clone`]; this requirement is for the benefit of implementing
/// [`Exhaust`] for containers of this type. (Hopefully, a future version of the library may relax
/// this restriction as a breaking change, as it does prevent reasonable implementations for types
/// such as atomics.)
///
/// # Examples
///
/// Using [the derive macro](macro@Exhaust) to implement the trait:
///
/// ```
/// use exhaust::Exhaust;
///
/// #[derive(Clone, PartialEq, Debug, Exhaust)]
/// struct Foo {
/// a: bool,
/// b: Bar,
/// }
///
/// #[derive(Clone, PartialEq, Debug, Exhaust)]
/// enum Bar {
/// One,
/// Two(bool),
/// }
///
/// assert_eq!(
/// Foo::exhaust().collect::<Vec<Foo>>(),
/// vec![
/// Foo { a: false, b: Bar::One },
/// Foo { a: false, b: Bar::Two(false) },
/// Foo { a: false, b: Bar::Two(true) },
/// Foo { a: true, b: Bar::One },
/// Foo { a: true, b: Bar::Two(false) },
/// Foo { a: true, b: Bar::Two(true) },
/// ],
/// );
/// ```
///
/// Writing a manual implementation of `Exhaust`:
///
/// ```
/// use exhaust::Exhaust;
///
/// #[derive(Clone)]
/// struct AsciiLetter(char);
///
/// impl Exhaust for AsciiLetter {
/// type Iter = ExhaustAsciiLetter;
/// fn exhaust() -> Self::Iter {
/// ExhaustAsciiLetter { next: 'A' }
/// }
/// }
///
/// #[derive(Clone)]
/// struct ExhaustAsciiLetter {
/// next: char
/// }
///
/// impl Iterator for ExhaustAsciiLetter {
/// type Item = AsciiLetter;
///
/// fn next(&mut self) -> Option<Self::Item> {
/// match self.next {
/// 'A'..='Y' | 'a'..='z' => {
/// let item = self.next;
/// self.next = char::from_u32(self.next as u32 + 1).unwrap();
/// Some(AsciiLetter(item))
/// }
/// 'Z' => {
/// self.next = 'a';
/// Some(AsciiLetter('Z'))
/// }
/// '{' => None, // ('z' + 1)
/// _ => unreachable!(),
/// }
/// }
/// }
///
/// assert_eq!(
/// AsciiLetter::exhaust().map(|l| l.0).collect::<String>(),
/// String::from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"),
/// );
/// ```
///
/// # Excluded Types
///
/// The following primitive or standard library types **do not implement** [`Exhaust`] for
/// particular reasons:
///
/// * References, because there's nowhere to stash the referent.
/// (This could be changed for small finite types, like `&bool`, but those are the same
/// sort of types which are unlikely to be used by reference.)
/// * Pointers, for the same reason as references (and we could generate invalid pointers,
/// but that would be almost certainly pointless).
/// * [`u64`], [`i64`], and [`f64`], because they are too large to feasibly exhaust.
/// * Types which do not implement [`Clone`]:
///
/// * [`core::cell::UnsafeCell`]
/// * [`std::sync::Mutex`] and `RwLock`
/// * [`core::sync::atomic::Atomic*`](core::sync::atomic)
///
/// A future version of the library might relax the [`Clone`] bound,
/// but this is currently impossible.
/// * Containers that permit duplicate items, and can therefore be unboundedly large:
/// * [`alloc::vec::Vec`]
/// * [`alloc::collections::VecDeque`]
/// * [`alloc::collections::LinkedList`]
/// * [`alloc::collections::BinaryHeap`]
///
/// * [`core::mem::ManuallyDrop`], because it would be a memory leak.
/// * [`core::mem::MaybeUninit`], because it is not useful to obtain a `MaybeUninit<T>`
/// value without knowing whether it is initialized, and if they are to be all
/// initialized, then `T::exhaust()` is just as good.
/// * [`core::ops::Range*`](core::ops), because it is ambiguous whether inverted (start > end)
/// ranges should be generated.
/// * [`std::io::ErrorKind`] and other explicitly non-exhaustive types.
/// * [`std::io::Stdout`] and other types whose sole use is in performing IO.