exhaust/
lib.rs

1#![no_std]
2
3//! This crate provides the [`Exhaust`] trait and derive macro, which allow iterating over
4//! all values of a given type.
5//!
6//! # Package features
7//!
8//! All features are enabled by default.
9//! If you set `default-features = false`, `exhaust` becomes `no_std` compatible.
10//! The `alloc` and `std` features add `Exhaust` implementations for
11//! the corresponding standard library crates.
12
13#![forbid(rust_2018_idioms)]
14#![forbid(unsafe_code)]
15#![warn(unreachable_pub)]
16#![warn(missing_docs)]
17#![warn(missing_debug_implementations)]
18#![warn(
19    clippy::alloc_instead_of_core,
20    clippy::std_instead_of_core,
21    clippy::std_instead_of_alloc
22)]
23#![warn(clippy::cast_lossless)]
24#![warn(clippy::exhaustive_enums)]
25#![warn(clippy::exhaustive_structs)]
26#![warn(clippy::pedantic)]
27
28#[cfg(feature = "alloc")]
29extern crate alloc;
30#[cfg(feature = "std")]
31extern crate std;
32
33/// Allows the derive macro to be used internally.
34extern crate self as exhaust;
35
36// -------------------------------------------------------------------------------------------------
37
38use core::fmt;
39use core::iter::FusedIterator;
40
41// -------------------------------------------------------------------------------------------------
42
43pub(crate) mod patterns;
44
45mod impls;
46
47pub mod iteration;
48
49#[cfg(doctest)]
50pub mod test_compile_fail;
51
52// -------------------------------------------------------------------------------------------------
53
54/// Types that can be exhaustively iterated. That is, an iterator is available which
55/// produces every possible value of this type.
56///
57/// # Properties
58///
59/// Implementations must have the following properties:
60///
61/// * Exhaustiveness: If [`Self: PartialEq`](PartialEq), then for every value `a` of type
62///   `Self`, there is some element `b` of `Self::exhaust()` for which `a == b`,
63///   unless it is the case that `a != a`.
64///
65///   If there is no `PartialEq` implementation, then follow the spirit of this rule anyway.
66///
67/// * No duplicates: if [`Self: PartialEq`](PartialEq), then for any two items `a, b` produced
68///   by the iterator, `a != b`.
69///
70///   If this rule comes into conflict with exhaustiveness, then exhaustiveness takes priority.
71///
72/// * If there is any value `a` of type `Self` for which `a != a`, then [`Exhaust`]
73///   must produce one or more such values (e.g. [`f32::NAN`]).
74///
75/// * The iterator has a finite length.
76///
77///   For example, collections which can contain arbitrary numbers of duplicate elements, like
78///   [`Vec`](alloc::vec::Vec), should not implement [`Exhaust`],
79///   because they cannot have an iterator which is both finite and exhaustive.
80///
81/// * Purity/determinism: every call to `Self::exhaust()`, or [`Clone::clone()`] of a returned
82///   iterator or factory, should produce the same sequence of items.
83///
84///   (If this is not upheld, then derived implementations of [`Exhaust`] on types containing
85///   this type will not behave consistently.)
86///
87/// * `exhaust()` does not panic, nor does the iterator it returns,
88///   except in the event that memory allocation fails.
89///
90/// * All produced values should be valid according to `Self`’s invariants as enforced by its
91///   ordinary constructors. When the above properties refer to “a value of type `Self`”,
92///   they do not include invalid values.
93///
94/// The following further properties are recommended when feasible:
95///
96/// * If `Self: Ord`, then the items are sorted in ascending order.
97///
98/// * The iterator’s length makes it feasible to actually exhaust.
99///
100///   For example, [`u64`] does not implement [`Exhaust`].
101///   This may be infeasible to ensure in compositions; e.g. `[u16; 4]` is even more infeasible
102///   to exhaust than [`u64`].
103///
104/// [`Exhaust`] is not an `unsafe trait`, and as such, no soundness property should rest
105/// on implementations having any of the above properties unless the particular implementation
106/// guarantees them.
107///
108/// # Examples
109///
110/// Using [`derive(Exhaust)`](macro@Exhaust) to implement the trait:
111///
112/// ```
113#[doc = include_str!("example-derive-usage.rs")]
114/// ```
115///
116/// Writing a manual implementation of `Exhaust`:
117///
118/// ```
119/// use exhaust::Exhaust;
120///
121/// #[derive(Clone, Debug)]
122/// struct AsciiLetter(char);
123///
124/// impl Exhaust for AsciiLetter {
125///     type Iter = ExhaustAsciiLetter;
126///
127///     // We could avoid needing to `derive(Clone, Debug)` by using `char` as the factory,
128///     // but if we did that, then `from_factory()` must check its argument for validity.
129///     type Factory = Self;
130///
131///     fn exhaust_factories() -> Self::Iter {
132///         ExhaustAsciiLetter { next: 'A' }
133///     }
134///
135///     fn from_factory(factory: Self::Factory) -> Self {
136///         factory
137///     }
138/// }
139///
140/// #[derive(Clone, Debug)]  // All `Exhaust::Iter`s must implement `Clone` and `Debug`.
141/// struct ExhaustAsciiLetter {
142///     next: char
143/// }
144///
145/// impl Iterator for ExhaustAsciiLetter {
146///     type Item = AsciiLetter;
147///
148///     fn next(&mut self) -> Option<Self::Item> {
149///         match self.next {
150///             'A'..='Y' | 'a'..='z' => {
151///                 let item = self.next;
152///                 self.next = char::from_u32(self.next as u32 + 1).unwrap();
153///                 Some(AsciiLetter(item))
154///             }
155///             'Z' => {
156///                 self.next = 'a';
157///                 Some(AsciiLetter('Z'))
158///             }
159///             '{' => None,  // ('z' + 1)
160///             _ => unreachable!(),
161///         }
162///     }
163/// }
164/// impl std::iter::FusedIterator for ExhaustAsciiLetter {}
165///
166/// assert_eq!(
167///     AsciiLetter::exhaust().map(|l| l.0).collect::<String>(),
168///     String::from("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"),
169/// );
170/// ```
171///
172/// # Excluded Types
173///
174/// The following primitive or standard library types **do not implement** [`Exhaust`] for
175/// particular reasons:
176///
177/// * References, because there's nowhere to stash the referent.
178///   (This could be changed for small finite types, like `&bool`, but those are the same
179///   sort of types which are unlikely to be used by reference.)
180/// * Pointers, for the same reason as references (and we could generate invalid pointers,
181///   but that would be almost certainly pointless).
182/// * [`u64`], [`i64`], and [`f64`], because they are too large to feasibly exhaust.
183/// * Containers that permit duplicate items, and can therefore be unboundedly large:
184///   * [`alloc::vec::Vec`]
185///   * [`alloc::collections::VecDeque`]
186///   * [`alloc::collections::LinkedList`]
187///   * [`alloc::collections::BinaryHeap`]
188///
189/// * [`core::mem::ManuallyDrop`], because it would be a memory leak.
190/// * [`core::mem::MaybeUninit`], because it is not useful to obtain a `MaybeUninit<T>`
191///   value without knowing whether it is initialized, and if they are to be all
192///   initialized, then `T::exhaust()` is just as good.
193/// * [`core::ops::Range` and `core::ops::RangeInclusive`](core::ops), because it is ambiguous
194///   whether inverted (start > end) ranges should be generated.
195/// * [`std::io::ErrorKind`] and other explicitly non-exhaustive types.
196pub trait Exhaust: Sized {
197    /// Iterator type returned by [`Self::exhaust_factories()`].
198    /// See the trait documentation for what properties this iterator should have.
199    ///
200    /// <div class="warning">
201    ///
202    /// Note: While it is necessary for this type to be exposed, an implementation of
203    /// [`Exhaust`] changing to another iterator type should not be considered a breaking
204    /// change, as long as it still has the same iterator properties (e.g.
205    /// [`ExactSizeIterator`]); it should be treated as an implementation detail.
206    ///
207    /// </div>
208    type Iter: core::iter::FusedIterator<Item = Self::Factory> + Clone + fmt::Debug;
209
210    /// Data which can be used to construct `Self`.
211    ///
212    /// The difference between `Self` and `Self::Factory` is that the `Factory` must
213    /// implement [`Clone`], while `Self` is not required to.
214    /// This is relevant to, and motivated by, the following cases:
215    ///
216    /// * Types which do not implement [`Clone`], or which conditionally implement [`Clone`],
217    ///   can still implement [`Exhaust`] by providing a `Factory` type which is not `Self`.
218    ///   For example, interior-mutable types often do not implement [`Clone`], or implement it
219    ///   so as to make a new handle to existing shared state; those types should choose a
220    ///   `Factory` type which represents their initial state only.
221    ///
222    /// * Generic containers of two or more values need to generate all combinations of their
223    ///   values.
224    ///   The guarantee that the contents’ `Factory` is [`Clone`] allows them to use clones of the
225    ///   factories to perform this iteration straightforwardly.
226    ///   (It would be theoretically possible to avoid this by cloning the exhausting iterators
227    ///   themselves, but much more complex and difficult to implement correctly.)
228    ///   For example, `[AtomicBool; 2]` ends up using `[bool; 2]` as its factory, which
229    ///   implements [`Clone`] even though [`AtomicBool`](core::sync::atomic::AtomicBool) does not.
230    ///
231    /// * A lot of wrapper types can easily implement [`Exhaust`] by delegating to another
232    ///   iterator and merely implementing [`Self::from_factory()`] to add the wrapper.
233    ///   This is not more powerful than use of [`Iterator::map()`], but it is often more
234    ///   convenient.
235    ///
236    /// Types which implement [`Clone`] and are not generic can use `type Factory = Self;`
237    /// if they wish.
238    ///
239    /// <div class="warning">
240    ///
241    /// Note: While it is necessary for this type to be exposed, an implementation of
242    /// [`Exhaust`] changing to another factory type should not be considered a breaking
243    /// change; it should be treated as an implementation detail, unless otherwise documented.
244    ///
245    /// </div>
246    type Factory: Clone + fmt::Debug;
247
248    /// Returns an iterator over all values of this type.
249    ///
250    /// See the trait documentation for what properties this iterator should have.
251    ///
252    /// This function is equivalent to `Self::exhaust_factories().map(Self::from_factory)`.
253    /// Implementors should not override it.
254    #[must_use]
255    #[mutants::skip]
256    fn exhaust() -> Iter<Self> {
257        Iter::default()
258    }
259
260    /// Returns an iterator over [factories](Self::Factory) for all values of this type.
261    ///
262    /// Implement this function to implement the trait. Call this function when implementing an
263    /// [`Exhaust::Iter`] iterator for a type that contains this type.
264    ///
265    /// See the trait documentation for what properties this iterator should have.
266    #[must_use]
267    fn exhaust_factories() -> Self::Iter;
268
269    /// Construct a concrete value of this type from a [`Self::Factory`] value produced by
270    /// its [`Self::Iter`].
271    ///
272    /// <div class="warning">
273    ///
274    /// Caution: While this function is meant to be used only with values produced by the iterator,
275    /// this cannot be enforced; therefore, make sure it cannot bypass any invariants that
276    /// the type might have.
277    ///
278    /// </div>
279    ///
280    /// # Panics
281    ///
282    /// - This function may panic if given a factory value that is not one of the values
283    ///   [`Self::Iter`] is able to produce.
284    /// - This function may panic or abort if memory allocation that is required to construct
285    ///   [`Self`] fails.
286    ///
287    /// Implementations should not panic under any other circumstances.
288    #[must_use]
289    fn from_factory(factory: Self::Factory) -> Self;
290}
291
292/// Derive macro generating an impl of the trait [`Exhaust`].
293///
294/// # Applicability
295///
296/// This macro may be applied to `struct`s and `enum`s, but not `union`s.
297/// All fields must have types which themselves implement [`Exhaust`].
298///
299/// <div class="warning">
300///
301/// If your type has invariants enforced through private fields, then do not use this derive macro,
302/// as that would make it possible to obtain instances with any values whatsoever.
303/// There is not currently any way to add constraints.
304///
305/// </div>
306///
307/// # Generated code
308///
309/// The macro generates the following items:
310///
311/// * An implementation of [`Exhaust`] for your type.
312///
313/// * A “factory” struct type for `<Self as Exhaust>::Factory`.
314///
315///   It has no public fields.
316///   It implements [`Clone`] and [`fmt::Debug`].
317///   It is unnameable except through the associated type, `<Self as Exhaust>::Factory`.
318///
319/// * An iterator struct type for `<Self as Exhaust>::Iter`.
320///
321///   It has no public fields.
322///   It implements [`Iterator`], [`FusedIterator`], [`Clone`], and [`fmt::Debug`],
323///   but not [`DoubleEndedIterator`] or [`ExactSizeIterator`].
324///   It does not currently override any of the optional iterator methods such as
325///   [`Iterator::size_hint()`].
326///   It is unnameable except through the associated type, `<Self as Exhaust>::Iter`.
327///
328/// The [`fmt::Debug`] implementations currently print only a placeholder with no details.
329/// This may be changed in future versions.
330///
331/// All of the generated types have names like `Exhaust<your type name><some suffix>`.
332/// Unfortunately, it is *possible* for these names to conflict with your code’s names;
333/// but conflicts will not occur as long as you avoid *using* any items named `ExhaustFoo*`
334/// from within a type named `Foo`.
335/// Items which are merely in the same module do not interfere, because only the code generated
336/// by the `derive(Exhaust)` macro is affected.
337///
338/// # Example
339///
340/// ```
341#[doc = include_str!("example-derive-usage.rs")]
342/// ```
343pub use exhaust_macros::Exhaust;
344
345// -------------------------------------------------------------------------------------------------
346
347/// Iterator over all values of any type that implements [`Exhaust`].
348///
349/// It may be obtained with [`T::exhaust()`](Exhaust::exhaust) or [`Default::default()`].
350pub struct Iter<T: Exhaust>(<T as Exhaust>::Iter);
351
352impl<T: Exhaust> Default for Iter<T> {
353    #[inline]
354    fn default() -> Self {
355        Self(T::exhaust_factories())
356    }
357}
358
359impl<T: Exhaust> Iterator for Iter<T> {
360    type Item = T;
361
362    #[inline]
363    fn next(&mut self) -> Option<Self::Item> {
364        self.0.next().map(T::from_factory)
365    }
366
367    #[inline]
368    fn size_hint(&self) -> (usize, Option<usize>) {
369        self.0.size_hint()
370    }
371
372    fn fold<B, F>(self, init: B, mut f: F) -> B
373    where
374        Self: Sized,
375        F: FnMut(B, Self::Item) -> B,
376    {
377        self.0.fold(init, |state, item_factory| {
378            f(state, T::from_factory(item_factory))
379        })
380    }
381}
382
383impl<T: Exhaust<Iter: DoubleEndedIterator>> DoubleEndedIterator for Iter<T> {
384    fn next_back(&mut self) -> Option<Self::Item> {
385        self.0.next_back().map(T::from_factory)
386    }
387
388    fn rfold<B, F>(self, init: B, mut f: F) -> B
389    where
390        Self: Sized,
391        F: FnMut(B, Self::Item) -> B,
392    {
393        self.0.rfold(init, |state, item_factory| {
394            f(state, T::from_factory(item_factory))
395        })
396    }
397}
398
399impl<T: Exhaust> FusedIterator for Iter<T> {
400    // Note: This is only correct because of the `FusedIterator` bound on `Exhaust::Iter`.
401    // Otherwise we would have to add a `T::Iter: FusedIterator` bound here too.
402}
403
404impl<T: Exhaust<Iter: ExactSizeIterator>> ExactSizeIterator for Iter<T> {}
405
406impl<T: Exhaust> Clone for Iter<T> {
407    #[inline]
408    fn clone(&self) -> Self {
409        Self(self.0.clone())
410    }
411}
412impl<T: Exhaust<Iter: Copy>> Copy for Iter<T> {}
413
414impl<T: Exhaust<Iter: fmt::Debug>> fmt::Debug for Iter<T> {
415    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
416        f.debug_tuple("exhaust::Iter").field(&self.0).finish()
417    }
418}