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
/// `Enumerable` is a trait for types that can have their possible values enumerated.
///
/// ## Overview
///
/// To enumerate all possible values of a `Enumerable` type, call the
/// [`enumerator`](Enumerable::enumerator) method, which returns an iterator of type
/// [`Self::Enumerator`](Enumerable::Enumerator).
///
/// It's also possible to get the number of possible values of a `Enumerable` type constantly by
/// accessing the [`ENUMERABLE_SIZE`](Enumerable::ENUMERABLE_SIZE) constant. If the number of
/// possible values exceeds `usize::MAX`, the constant will panic at compile time. To avoid this,
/// use [`ENUMERABLE_SIZE_OPTION`](Enumerable::ENUMERABLE_SIZE_OPTION) instead. It's
/// `Some(ENUMERABLE_SIZE)` if it does not exceed `usize::MAX`, `None` otherwise.
///
/// ## Built-in Implementations
///
/// The following types have built-in implementations of the `Enumerable` trait:
/// - `bool`: Yields `false` and then `true`.
/// - Numeric types: Yields all possible values of the type from the minimum to the maximum one.
/// - [`Option`]: Yields `None` and then `Some(item)` for each possible value of `T`.
/// - [`Result`]: Yields `Ok(item)` for each possible value of `T` and then `Err(error)` for each
/// possible value of `E`.
/// - `char`: Yields all possible Unicode scalar values, i.e. all code points ranging from `U+0000`
/// to `U+10FFFF`, excluding the surrogate code points (`U+D800` to `U+DFFF`), from the lowest to
/// the highest one.
/// - Tuples: Yields all possible values of the tuple with 1 to 16 elements, in a lexicographic
/// ordering (as [`core::cmp::Ord`] does), provided that all elements implement `Enumerable`.
/// - `()`: Yields the unit value `()`.
///
/// ## Derivable
///
/// This trait can be derived using `#[derive(Enumerable)]` on structs and enums, if
/// - they have no fields, or
/// - all of their fields implement `Enumerable`.
///
/// If the type has generic parameters, they must also meet the following requirements:
/// - there are only type parameters, i.e. no lifetime or const parameters, and
/// - all type parameters implement [`Copy`].
///
/// See "Guarantees and Limitations" below for more information.
///
/// ### Customizing the Generated Enumerator
///
/// In most cases, `#[derive(Enumerable)]` will generate a new enumerator type named
/// `<Type>Enumerator` in the same module, with the same visibility and generic parameters as the
/// type to be derived `<Type>`. It's possible to customize the name of the generated type by using
/// - `#[enumerator = "DesiredEnumeratorName"]`, or
/// - `#[enumerator(DesiredEnumeratorName)]`,
///
/// they are equivalent.
///
/// `#[derive(Enumerable)]` will NOT generate an enumerator type when the type to be derived is
/// - an enum with zero variants,
/// - an enum with no fields, or
/// - a struct with no fields,
///
/// in these cases, the custom enumerator name will be ignored.
///
/// ## Guarantees and Requirements
///
/// It is guaranteed that:
/// - The derived implementations will enumerate over all possible variants of an enum in the order
/// they are declared. Variants with fields of uninhabited types (e.g. empty enums) will be
/// skipped.
/// - The derived implementations will yield all possible values of a struct (or a variant with some
/// fields of an enum) in a lexicographic ordering based on the top-to-bottom declaration order of
/// the fields, as built-in implementations for tuples do.
///
/// It is **NOT** guaranteed that:
/// - The derived and the built-in implementations will return a specific type of [`Iterator`] as
/// enumerators.
///
/// Do **NOT** rely on the specific type of the enumerator provided by an `Enumerable` type,
/// unless you are using `#[enumerator(...)]` and knowing that `#[derive(Enumerable)]` will
/// generate an enumerator type, use `<T as Enumerable>::Enumerator` instead in all other cases.
///
/// It is **REQUIRED** that if you are implementing `Enumerable` for a type manually, your
/// enumerator should:
/// - have a idempotent `enumerator()` method, i.e. calling it multiple times should return
/// iterators that yield the same values in the same order. Multiple calls to `enumerator()`
/// should not affect each other.
/// - have a `ENUMERABLE_SIZE_OPTION` constant that matches the number of elements returned by
/// `enumerator()`.
/// - use the default version of `ENUMERABLE_SIZE`, or provide a custom one that matches
/// `ENUMERABLE_SIZE_OPTION`.
///
/// Failed to meet the requirements will result in unexpected behavior when interacting with the
/// derived implementations.
///
/// ## Example
///
/// ```
/// use enumerable::Enumerable;
///
/// #[derive(Copy, Clone, Eq, PartialEq, Debug, Enumerable)]
/// enum SomeEnum { A, B, C }
///
/// let mut enumerated = SomeEnum::enumerator().collect::<Vec<_>>();
/// assert_eq!(enumerated, vec![SomeEnum::A, SomeEnum::B, SomeEnum::C]);
///
/// let mut enumerated = Option::<SomeEnum>::enumerator().collect::<Vec<_>>();
/// assert_eq!(enumerated, vec![None, Some(SomeEnum::A), Some(SomeEnum::B), Some(SomeEnum::C)]);
/// ```
///
pub use *;
pub use *;
pub use *;