1#![warn(anonymous_parameters)]
40#![warn(bad_style)]
41#![warn(bare_trait_objects)]
42#![warn(const_err)]
43#![warn(dead_code)]
44#![warn(elided_lifetimes_in_paths)]
45#![warn(improper_ctypes)]
46#![warn(missing_copy_implementations)]
47#![warn(missing_debug_implementations)]
48#![warn(missing_doc_code_examples)]
49#![warn(missing_docs)]
50#![warn(no_mangle_generic_items)]
51#![warn(non_shorthand_field_patterns)]
52#![warn(nonstandard_style)]
53#![warn(overflowing_literals)]
54#![warn(path_statements)]
55#![warn(patterns_in_fns_without_body)]
56#![warn(private_in_public)]
57#![warn(rust_2018_idioms)]
58#![warn(trivial_casts)]
59#![warn(trivial_numeric_casts)]
60#![warn(unconditional_recursion)]
61#![warn(unreachable_pub)]
62#![warn(unused)]
63#![warn(unused_allocation)]
64#![warn(unused_comparisons)]
65#![warn(unused_parens)]
66#![warn(unused_qualifications)]
67#![warn(unused_results)]
68#![warn(variant_size_differences)]
69#![warn(while_true)]
70
71#[cfg(feature = "serde")]
73use serde::{ Serialize, Deserialize };
74
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
81#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
82pub enum Few<T> {
83 Zero,
85 One(T),
87 Two(T, T),
89}
90
91impl<T> Few<T> {
92 pub fn is_zero(&self) -> bool {
94 match self {
95 Few::Zero => true,
96 _ => false,
97 }
98 }
99
100 pub fn is_one(&self) -> bool {
102 match self {
103 Few::One(_) => true,
104 _ => false,
105 }
106 }
107
108 pub fn is_two(&self) -> bool {
110 match self {
111 Few::Two(_, _) => true,
112 _ => false,
113 }
114 }
115
116 pub fn contains<U>(&self, x: &U) -> bool
119 where U: PartialEq<T>
120 {
121 match self {
122 Few::Zero => false,
123 Few::One(v) => x == v,
124 Few::Two(a, b) => x == a || x == b,
125 }
126 }
127
128 pub fn map<F, U>(self, mut f: F) -> Few<U>
130 where F: FnMut(T) -> U,
131 {
132 match self {
133 Few::Zero => Few::Zero,
134 Few::One(v) => Few::One((f)(v)),
135 Few::Two(a, b) => Few::Two((f)(a), (f)(b)),
136 }
137 }
138}
139
140impl<T> Iterator for Few<T> {
141 type Item = T;
142
143 fn next(&mut self) -> Option<T> {
144 let mut res = None;
145 replace_with(self, |curr|
146 match curr {
147 Few::Zero => { res = None; Few::Zero },
148 Few::One(v) => { res = Some(v); Few::Zero },
149 Few::Two(a, b) => { res = Some(a); Few::One(b) },
150 }
151 );
152 res
153 }
154}
155
156impl<T> DoubleEndedIterator for Few<T> {
157 fn next_back(&mut self) -> Option<T> {
158 let mut res = None;
159 replace_with(self, |curr|
160 match curr {
161 Few::Zero => { res = None; Few::Zero },
162 Few::One(v) => { res = Some(v); Few::Zero },
163 Few::Two(a, b) => { res = Some(b); Few::One(a) },
164 }
165 );
166 res
167 }
168}
169
170impl<T> ExactSizeIterator for Few<T> {
171 fn len(&self) -> usize {
172 match self {
173 Few::Zero => 0,
174 Few::One(_) => 1,
175 Few::Two(_, _) => 2,
176 }
177 }
178}
179
180impl<T> std::iter::FusedIterator for Few<T> {}
181
182
183impl<T> Default for Few<T> {
184 fn default() -> Self {
185 Few::Zero
186 }
187}
188
189impl<T> From<T> for Few<T> {
190 fn from(value: T) -> Self {
191 Few::One(value)
192 }
193}
194
195impl<T> From<(T, T)> for Few<T> {
196 fn from(value: (T, T)) -> Self {
197 Few::Two(value.0, value.1)
198 }
199}
200
201impl<T> From<Option<T>> for Few<T> {
202 fn from(value: Option<T>) -> Self {
203 match value {
204 None => Few::Zero,
205 Some(value) => Few::One(value),
206 }
207 }
208}
209
210impl<T> From<Option<(T, T)>> for Few<T> {
211 fn from(value: Option<(T, T)>) -> Self {
212 match value {
213 None => Few::Zero,
214 Some((a, b)) => Few::Two(a, b),
215 }
216 }
217}
218
219impl<T> From<(Option<T>, Option<T>)> for Few<T> {
220 fn from(value: (Option<T>, Option<T>)) -> Self {
221 match (value.0, value.1) {
222 (None, None) => Few::Zero,
223 (Some(a), None) => Few::One(a),
224 (None, Some(b)) => Few::One(b),
225 (Some(a), Some(b)) => Few::Two(a, b),
226 }
227 }
228}
229
230impl<T> Into<Option<(T, T)>> for Few<T> where T: Clone {
231 fn into(self) -> Option<(T, T)> {
232 match self {
233 Few::Zero => None,
234 Few::One(v) => Some((v.clone(), v)),
235 Few::Two(a, b) => Some((a, b)),
236 }
237 }
238}
239
240
241#[inline]
247fn replace_with<T, F>(val: &mut T, replace: F)
248 where F: FnOnce(T) -> T {
249 let guard = ExitGuard;
250
251 unsafe {
252 let old = std::ptr::read(val);
253 let new = replace(old);
254 std::ptr::write(val, new);
255 }
256
257 std::mem::forget(guard);
258}
259
260struct ExitGuard;
261
262impl Drop for ExitGuard {
263 fn drop(&mut self) {
264 panic!("`replace_with` closure unwind");
265 }
266}