validated/lib.rs
1//! The cumulative sibling of `Result` and `Either`.
2//!
3//! The [`Validated`] type has special `FromIterator` instances that enable
4//! _all_ errors in a sequence to be reported, not just the first one.
5//!
6//! # Motivation
7//!
8//! We might think of [`Iterator::collect`] as being for consolidating the
9//! result of some chained iteration into a concrete container, like `Vec`.
10//!
11//! ```
12//! let v = vec![1,2,3];
13//! assert_eq!(vec![2,4,6], v.into_iter().map(|n| n * 2).collect::<Vec<u32>>());
14//! ```
15//!
16//! But `collect` isn't limited to this; it can be used to "fold" down into any
17//! type you like, provided that it implements [`FromIterator`]. Consider the
18//! effects of such an `impl` for `Result`:
19//!
20//! ```
21//! let v: Vec<u32> = vec![1, 2, 3];
22//! let r: Result<Vec<u32>, &str> = v
23//! .into_iter()
24//! .map(|n| if n % 2 == 0 { Err("Oh no!") } else { Ok(n * 2) })
25//! .collect();
26//! assert_eq!(Err("Oh no!"), r);
27//! ```
28//!
29//! The `Result` has been "interweaved" and pulled back out. Critically, this
30//! `collect` call short-circuits; `n * 2` is never called for `3`, since the
31//! `map` "fails" at `2`. This is useful when we require a sequence of IO
32//! actions to all succeed and we wish to cancel remaining operations as soon
33//! as any error occurs.
34//!
35//! But what if we don't want to short circuit? What if we want a report of all
36//! the errors that occurred?
37//!
38//! ## Cumulative Errors and `Validated`
39//!
40//! Consider three cases where we'd want a report of all errors, not just the
41//! first one:
42//!
43//! 1. Form input validation.
44//! 2. Type checking.
45//! 3. Concurrent IO.
46//!
47//! In the first case, if a user makes several input mistakes, it's the best
48//! experience for them if all errors are reported at once so that they can make
49//! their corrections in a single pass.
50//!
51//! In the second case, knowing only the first detected type error might not
52//! actually be the site of the real issue. We need everything that's broken to
53//! be reported so we can make the best decision of what to fix.
54//!
55//! In the third case, it may be that halting your entire concurrent job upon
56//! detection of a single failure isn't appropriate. You might instead want
57//! everything to finish as it can, and then collect a bundle of errors at the
58//! end.
59//!
60//! The [`Validated`] type accomodates these use cases; it is a "cumulative `Result`".
61//!
62//! ```
63//! use validated::Validated::{self, Good, Fail};
64//! use nonempty_collections::*;
65//!
66//! let v = vec![Good(1), Validated::fail("No!"), Good(3), Validated::fail("Ack!")];
67//! let r: Validated<Vec<u32>, &str> = Fail(nev!["No!", "Ack!"]);
68//! assert_eq!(r, v.into_iter().collect());
69//! ```
70//!
71//! ## Use of non-empty Vectors (`NEVec`)
72//!
73//! In the spirit of "make illegal states unrepresentable", the [`Fail`] variant
74//! of `Validated` contains a [`NEVec`], a non-empty `Vec`. `NEVec` can do
75//! everything that `Vec` can do, plus some additional benefits. In the case of
76//! this crate, this representation forbids the otherwise meaningless `Fail(vec![])`.
77//!
78//! In other words, if you have a `Validated<T, E>`, you either have a concrete
79//! `T`, or **at least one** `E`.
80//!
81//! # Features
82//!
83//! - `rayon`: Enable `FromParallelIterator` instances for `Validated`.
84//!
85//! # Resources
86//!
87//! - [Haskell: Validation][haskell]
88//! - [Scala: Cats `Validated`][cats]
89//!
90//! [haskell]: https://hackage.haskell.org/package/validation
91//! [cats]: https://typelevel.org/cats/datatypes/validated.html
92
93#![warn(missing_docs)]
94#![doc(html_root_url = "https://docs.rs/validated/0.4.1")]
95
96use crate::Validated::{Fail, Good};
97use std::iter::{FromIterator, Sum};
98use std::ops::{Deref, DerefMut};
99
100use nonempty_collections::{nev, NEVec, NonEmptyIterator};
101#[cfg(feature = "rayon")]
102use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelIterator};
103#[cfg(feature = "rayon")]
104use std::sync::Mutex;
105
106/// Similar to [`Result`], but cumulative in its error type.
107///
108/// # Error weaving
109///
110/// Consider that when using `collect` in a "Traversable" way to pull a single
111/// `Result` out of an `Iterator` containing many `Result`s, it will fail on the
112/// first `Err` and short-circuit the iteration. This is suboptimal if we wish
113/// to be made aware of every failure that (would have) occurred.
114///
115/// ```
116/// use validated::Validated::{self, Good, Fail};
117/// use nonempty_collections::*;
118///
119/// let v = vec![Ok(1), Ok(2), Ok(3)];
120/// let r: Validated<Vec<u32>, &str> = Good(vec![1, 2, 3]);
121/// assert_eq!(r, v.into_iter().collect());
122///
123/// let v = vec![Ok(1), Err("Oh!"), Ok(2), Err("No!"), Ok(3)];
124/// let r: Validated<Vec<u32>, &str> = Fail(nev!["Oh!", "No!"]);
125/// assert_eq!(r, v.into_iter().collect());
126/// ```
127///
128/// Naturally iterators of `Validated` values can be collected in a similar way:
129///
130/// ```
131/// use validated::Validated::{self, Good, Fail};
132/// use nonempty_collections::*;
133///
134/// let v = vec![Good(1), Good(2), Good(3)];
135/// let r: Validated<Vec<u32>, &str> = Good(vec![1, 2, 3]);
136/// assert_eq!(r, v.into_iter().collect());
137///
138/// let v = vec![Good(1), Validated::fail("No!"), Good(3), Validated::fail("Ack!")];
139/// let r: Validated<Vec<u32>, &str> = Fail(nev!["No!", "Ack!"]);
140/// assert_eq!(r, v.into_iter().collect());
141/// ```
142///
143/// # Mapping composite results
144///
145/// This type also provides `mapN` methods, which are surprisingly missing on
146/// `Option` and `Result`.
147///
148/// ```
149/// use validated::Validated::{self, Good, Fail};
150///
151/// let v: Validated<u32, &str> = Good(1).map3(Good(2), Good(3), |a, b, c| a + b + c);
152/// assert_eq!(v, Good(6));
153/// ```
154///
155/// For `Validated` in particular these are quite useful, as a meaningful
156/// `and_then` cannot be written for it.
157///
158/// Formally, `Validated` is not a Monad, but it is an Applicative Functor.
159#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
160pub enum Validated<T, E> {
161 /// Analogous to [`Result::Ok`].
162 Good(T),
163 /// Analogous to [`Result::Err`], except that the error type is cumulative.
164 Fail(NEVec<E>),
165}
166
167impl<T, E> Validated<T, E> {
168 /// Fail with the given error.
169 pub fn fail(e: E) -> Validated<T, E> {
170 Fail(nev![e])
171 }
172
173 /// Converts from `&mut Validated<T, E>` to `Validated<&mut T, &mut E>`.
174 ///
175 /// **Note:** In the case of [`Fail`], a new `Vec` of references is
176 /// allocated.
177 pub fn as_mut(&mut self) -> Validated<&mut T, &mut E> {
178 match self {
179 Good(ref mut t) => Good(t),
180 Fail(ref mut e) => {
181 let ne = e.nonempty_iter_mut().collect();
182 Fail(ne)
183 }
184 }
185 }
186
187 /// Converts from `&Validated<T, E>` to `Validated<&T, &E>`.
188 ///
189 /// Produces a new `Validated`, containing references to the original,
190 /// leaving the original in place.
191 ///
192 /// **Note:** In the case of [`Fail`], a new `Vec` of references is
193 /// allocated.
194 pub fn as_ref(&self) -> Validated<&T, &E> {
195 match self {
196 Good(ref t) => Good(t),
197 Fail(e) => {
198 let ne = e.nonempty_iter().collect();
199 Fail(ne)
200 }
201 }
202 }
203
204 /// Returns the contained [`Good`] value, consuming `self`.
205 ///
206 /// # Panics
207 ///
208 /// Panics with a custom message if `self` is actually the `Fail`
209 /// variant.
210 pub fn expect(self, msg: &str) -> T {
211 match self {
212 Good(t) => t,
213 Fail(_) => panic!("{}", msg),
214 }
215 }
216
217 /// Was a given `Validated` operation completely successful?
218 pub fn is_good(&self) -> bool {
219 matches!(self, Good(_))
220 }
221
222 /// Did a given `Validated` operation have at least one failure?
223 pub fn is_fail(&self) -> bool {
224 matches!(self, Fail(_))
225 }
226
227 /// Returns an iterator over the possibly contained value.
228 ///
229 /// The iterator yields one value if the result is [`Good`], otherwise
230 /// nothing.
231 pub fn iter(&self) -> Iter<'_, T> {
232 Iter {
233 inner: self.as_ref().ok().ok(),
234 }
235 }
236
237 /// Returns a mutable iterator over the possibly contained value.
238 ///
239 /// The iterator yields one value if the result is [`Good`], otherwise
240 /// nothing.
241 pub fn iter_mut(&mut self) -> IterMut<'_, T> {
242 IterMut {
243 inner: self.as_mut().ok().ok(),
244 }
245 }
246
247 /// Applies a function to the `T` value of a [`Good`] variant, or leaves
248 /// a [`Fail`] variant untouched.
249 ///
250 /// ```
251 /// use validated::Validated::{self, Good, Fail};
252 ///
253 /// let v: Validated<u32, &str> = Good(1);
254 /// let r = v.map(|n| n * 2);
255 /// assert_eq!(r, Good(2));
256 ///
257 /// let v: Validated<u32, &str> = Validated::fail("No!");
258 /// let r = v.map(|n| n * 2);
259 /// assert_eq!(r, Validated::fail("No!"));
260 /// ```
261 pub fn map<U, F>(self, op: F) -> Validated<U, E>
262 where
263 F: FnOnce(T) -> U,
264 {
265 match self {
266 Good(t) => Good(op(t)),
267 Fail(e) => Fail(e),
268 }
269 }
270
271 /// Applies a function to the `Vec<E>` of a [`Fail`] variant, or leaves a
272 /// [`Good`] variant untouched.
273 pub fn map_err<R, F>(self, op: F) -> Validated<T, R>
274 where
275 F: FnOnce(NEVec<E>) -> NEVec<R>,
276 {
277 match self {
278 Good(t) => Good(t),
279 Fail(e) => Fail(op(e)),
280 }
281 }
282
283 /// Maps a function over two `Validated`, but only if both are of the
284 /// `Good` variant. If both failed, then their errors are concatenated.
285 ///
286 /// ```
287 /// use validated::Validated::{self, Good, Fail};
288 ///
289 /// let v: Validated<u32, &str> = Good(1).map2(Good(2), |a, b| a + b);
290 /// assert_eq!(v, Good(3));
291 ///
292 /// let v: Validated<u32, &str> = Good(1).map2(Validated::fail("No!"), |a, b: u32| a + b);
293 /// assert_eq!(v, Validated::fail("No!"));
294 /// ```
295 pub fn map2<U, Z, F>(self, vu: Validated<U, E>, f: F) -> Validated<Z, E>
296 where
297 F: FnOnce(T, U) -> Z,
298 {
299 match (self, vu) {
300 (Good(t), Good(u)) => Good(f(t, u)),
301 (Good(_), Fail(e)) => Fail(e),
302 (Fail(e), Good(_)) => Fail(e),
303 (Fail(mut e0), Fail(e1)) => {
304 e0.extend(e1);
305 Fail(e0)
306 }
307 }
308 }
309
310 /// Maps a function over three `Validated`, but only if all three are of the
311 /// `Good` variant. If any failed, then their errors are concatenated.
312 ///
313 /// ```
314 /// use validated::Validated::{self, Good, Fail};
315 ///
316 /// let v: Validated<u32, &str> = Good(1).map3(Good(2), Good(3), |a, b, c| a + b + c);
317 /// assert_eq!(v, Good(6));
318 ///
319 /// let v: Validated<u32, &str> = Good(1).map3(Good(2), Validated::fail("No!"), |a, b, c: u32| a + b + c);
320 /// assert_eq!(v, Validated::fail("No!"));
321 /// ```
322 pub fn map3<U, V, Z, F>(self, vu: Validated<U, E>, vv: Validated<V, E>, f: F) -> Validated<Z, E>
323 where
324 F: FnOnce(T, U, V) -> Z,
325 {
326 match (self, vu, vv) {
327 (Good(t), Good(u), Good(v)) => Good(f(t, u, v)),
328 (Good(_), Good(_), Fail(e)) => Fail(e),
329 (Good(_), Fail(e), Good(_)) => Fail(e),
330 (Fail(e), Good(_), Good(_)) => Fail(e),
331 (Good(_), Fail(e0), Fail(e1)) => Fail(nons(e0, Some(e1).into_iter())),
332 (Fail(e0), Good(_), Fail(e1)) => Fail(nons(e0, Some(e1).into_iter())),
333 (Fail(e0), Fail(e1), Good(_)) => Fail(nons(e0, Some(e1).into_iter())),
334 (Fail(e0), Fail(e1), Fail(e2)) => Fail(nons(e0, vec![e1, e2].into_iter())),
335 }
336 }
337
338 /// Maps a function over four `Validated`, but only if all four are of the
339 /// `Good` variant. If any failed, then their errors are concatenated.
340 pub fn map4<U, V, W, Z, F>(
341 self,
342 vu: Validated<U, E>,
343 vv: Validated<V, E>,
344 vw: Validated<W, E>,
345 f: F,
346 ) -> Validated<Z, E>
347 where
348 F: FnOnce(T, U, V, W) -> Z,
349 {
350 match (self, vu, vv, vw) {
351 (Good(t), Good(u), Good(v), Good(w)) => Good(f(t, u, v, w)),
352 (Good(_), Good(_), Good(_), Fail(e)) => Fail(e),
353 (Good(_), Good(_), Fail(e), Good(_)) => Fail(e),
354 (Good(_), Fail(e), Good(_), Good(_)) => Fail(e),
355 (Fail(e), Good(_), Good(_), Good(_)) => Fail(e),
356 (Good(_), Good(_), Fail(e0), Fail(e1)) => Fail(nons(e0, Some(e1).into_iter())),
357 (Good(_), Fail(e0), Good(_), Fail(e1)) => Fail(nons(e0, Some(e1).into_iter())),
358 (Good(_), Fail(e0), Fail(e1), Good(_)) => Fail(nons(e0, Some(e1).into_iter())),
359 (Fail(e0), Good(_), Good(_), Fail(e1)) => Fail(nons(e0, Some(e1).into_iter())),
360 (Fail(e0), Fail(e1), Good(_), Good(_)) => Fail(nons(e0, Some(e1).into_iter())),
361 (Fail(e0), Good(_), Fail(e1), Good(_)) => Fail(nons(e0, Some(e1).into_iter())),
362 (Good(_), Fail(e0), Fail(e1), Fail(e2)) => Fail(nons(e0, vec![e1, e2].into_iter())),
363 (Fail(e0), Good(_), Fail(e1), Fail(e2)) => Fail(nons(e0, vec![e1, e2].into_iter())),
364 (Fail(e0), Fail(e1), Good(_), Fail(e2)) => Fail(nons(e0, vec![e1, e2].into_iter())),
365 (Fail(e0), Fail(e1), Fail(e2), Good(_)) => Fail(nons(e0, vec![e1, e2].into_iter())),
366 (Fail(e0), Fail(e1), Fail(e2), Fail(e3)) => {
367 Fail(nons(e0, vec![e1, e2, e3].into_iter()))
368 }
369 }
370 }
371
372 /// Converts `self` into a [`Result`].
373 pub fn ok(self) -> Result<T, NEVec<E>> {
374 match self {
375 Good(t) => Ok(t),
376 Fail(e) => Err(e),
377 }
378 }
379
380 /// Returns the contained [`Good`] value, consuming `self`.
381 ///
382 /// # Examples
383 ///
384 /// ```
385 /// use validated::Validated;
386 ///
387 /// let v: Validated<u32, &str> = Validated::Good(1);
388 /// assert_eq!(v.unwrap(), 1);
389 /// ```
390 ///
391 /// # Panics
392 ///
393 /// Panics if `self` is actually the `Fail` variant.
394 pub fn unwrap(self) -> T {
395 match self {
396 Good(t) => t,
397 Fail(_) => panic!("called `Validated::unwrap` on a `Fail` value"),
398 }
399 }
400
401 /// Returns the contained [`Good`] value or a provided default.
402 ///
403 /// Arguments passed to `unwrap_or` are eagerly evaluated; if you are
404 /// passing the result of a function call, it is recommended to use
405 /// [`Validated::unwrap_or_else`] instead.
406 ///
407 /// # Examples
408 ///
409 /// ```
410 /// use validated::Validated;
411 ///
412 /// let v: Validated<u32, &str> = Validated::Good(1);
413 /// assert_eq!(v.unwrap_or(2), 1);
414 ///
415 /// let v: Validated<u32, &str> = Validated::fail("Oh no!");
416 /// assert_eq!(v.unwrap_or(2), 2);
417 /// ```
418 pub fn unwrap_or(self, default: T) -> T {
419 match self {
420 Good(t) => t,
421 Fail(_) => default,
422 }
423 }
424
425 /// Returns the contained [`Good`] value or computes it from a closure.
426 pub fn unwrap_or_else<F>(self, op: F) -> T
427 where
428 F: FnOnce(NEVec<E>) -> T,
429 {
430 match self {
431 Good(t) => t,
432 Fail(e) => op(e),
433 }
434 }
435}
436
437impl<T: Default, E> Validated<T, E> {
438 /// Returns the contained [`Good`] value or the default for `T`.
439 pub fn unwrap_or_default(self) -> T {
440 match self {
441 Good(t) => t,
442 Fail(_) => Default::default(),
443 }
444 }
445}
446
447impl<T: Deref, E> Validated<T, E> {
448 /// Like [`Result::as_deref`].
449 pub fn as_deref(&self) -> Validated<&T::Target, &E> {
450 self.as_ref().map(|t| t.deref())
451 }
452}
453
454impl<T: DerefMut, E> Validated<T, E> {
455 /// Like [`Result::as_deref_mut`].
456 pub fn as_deref_mut(&mut self) -> Validated<&mut T::Target, &mut E> {
457 self.as_mut().map(|t| t.deref_mut())
458 }
459}
460
461impl<T, E> From<Result<T, E>> for Validated<T, E> {
462 fn from(r: Result<T, E>) -> Self {
463 match r {
464 Ok(t) => Good(t),
465 Err(e) => Fail(NEVec::new(e)),
466 }
467 }
468}
469
470// FIXME Can't do it...
471// impl<T, E> FromIterator<NonEmpty<E>> for Validated<T, E> {
472// fn from_iter<I: IntoIterator<Item = NonEmpty<E>>>(iter: I) -> Self {
473// todo!()
474// }
475// }
476
477impl<T, U, E> FromIterator<Result<T, E>> for Validated<U, E>
478where
479 U: FromIterator<T>,
480{
481 fn from_iter<I: IntoIterator<Item = Result<T, E>>>(iter: I) -> Self {
482 let mut errors = Vec::new();
483
484 let result = iter
485 .into_iter()
486 .filter_map(|item| match item {
487 Ok(t) => Some(t),
488 Err(e) => {
489 errors.push(e);
490 None
491 }
492 })
493 .collect();
494
495 match NEVec::try_from_vec(errors) {
496 None => Good(result),
497 Some(e) => Fail(e),
498 }
499 }
500}
501
502impl<T, U, E> FromIterator<Validated<T, E>> for Validated<U, E>
503where
504 U: FromIterator<T>,
505{
506 fn from_iter<I: IntoIterator<Item = Validated<T, E>>>(iter: I) -> Self {
507 let mut errors = Vec::new();
508
509 let result = iter
510 .into_iter()
511 .filter_map(|item| match item {
512 Good(t) => Some(t),
513 Fail(e) => {
514 errors.extend(e);
515 None
516 }
517 })
518 .collect();
519
520 match NEVec::try_from_vec(errors) {
521 None => Good(result),
522 Some(e) => Fail(e),
523 }
524 }
525}
526
527#[cfg(feature = "rayon")]
528impl<T, U, E> FromParallelIterator<Result<T, E>> for Validated<U, E>
529where
530 T: Send,
531 E: Send,
532 U: FromParallelIterator<T>,
533{
534 fn from_par_iter<I>(par_iter: I) -> Validated<U, E>
535 where
536 I: IntoParallelIterator<Item = Result<T, E>>,
537 {
538 let errors = Mutex::new(Vec::new());
539
540 let result = par_iter
541 .into_par_iter()
542 .filter_map(|item| match item {
543 Ok(t) => Some(t),
544 Err(e) => {
545 errors.lock().unwrap().push(e);
546 None
547 }
548 })
549 .collect();
550
551 match NEVec::try_from_vec(errors.into_inner().unwrap()) {
552 None => Good(result),
553 Some(e) => Fail(e),
554 }
555 }
556}
557
558#[cfg(feature = "rayon")]
559impl<T, U, E> FromParallelIterator<Validated<T, E>> for Validated<U, E>
560where
561 T: Send,
562 E: Send,
563 U: FromParallelIterator<T>,
564{
565 fn from_par_iter<I>(par_iter: I) -> Validated<U, E>
566 where
567 I: IntoParallelIterator<Item = Validated<T, E>>,
568 {
569 let errors = Mutex::new(Vec::new());
570
571 let result = par_iter
572 .into_par_iter()
573 .filter_map(|item| match item {
574 Good(t) => Some(t),
575 Fail(e) => {
576 errors.lock().unwrap().extend(e);
577 None
578 }
579 })
580 .collect();
581
582 match NEVec::try_from_vec(errors.into_inner().unwrap()) {
583 None => Good(result),
584 Some(e) => Fail(e),
585 }
586 }
587}
588
589impl<T, E> IntoIterator for Validated<T, E> {
590 type Item = T;
591 type IntoIter = IntoIter<T>;
592
593 fn into_iter(self) -> Self::IntoIter {
594 IntoIter {
595 inner: self.ok().ok(),
596 }
597 }
598}
599
600impl<'a, T, E> IntoIterator for &'a Validated<T, E> {
601 type Item = &'a T;
602 type IntoIter = Iter<'a, T>;
603
604 fn into_iter(self) -> Iter<'a, T> {
605 self.iter()
606 }
607}
608
609impl<'a, T, E> IntoIterator for &'a mut Validated<T, E> {
610 type Item = &'a mut T;
611 type IntoIter = IterMut<'a, T>;
612
613 fn into_iter(self) -> IterMut<'a, T> {
614 self.iter_mut()
615 }
616}
617
618impl<T, U, E> Sum<Validated<U, E>> for Validated<T, E>
619where
620 T: Sum<U>,
621{
622 fn sum<I>(iter: I) -> Self
623 where
624 I: Iterator<Item = Validated<U, E>>,
625 {
626 let mut errors = Vec::new();
627
628 let result = iter
629 .filter_map(|item| match item {
630 Good(n) => Some(n),
631 Fail(e) => {
632 errors.extend(e);
633 None
634 }
635 })
636 .sum();
637
638 match NEVec::try_from_vec(errors) {
639 None => Good(result),
640 Some(e) => Fail(e),
641 }
642 }
643}
644
645/// ```
646/// use validated::Validated;
647///
648/// let ns: Validated<u32, ()> = [Ok(1), Ok(2), Ok(3)].into_iter().sum();
649/// assert_eq!(Validated::Good(6), ns);
650/// ```
651impl<T, U, E> Sum<Result<U, E>> for Validated<T, E>
652where
653 T: Sum<U>,
654{
655 fn sum<I>(iter: I) -> Self
656 where
657 I: Iterator<Item = Result<U, E>>,
658 {
659 let mut errors = Vec::new();
660
661 let result = iter
662 .filter_map(|item| match item {
663 Ok(n) => Some(n),
664 Err(e) => {
665 errors.push(e);
666 None
667 }
668 })
669 .sum();
670
671 match NEVec::try_from_vec(errors) {
672 None => Good(result),
673 Some(e) => Fail(e),
674 }
675 }
676}
677
678/// An iterator over a reference to the [`Good`] variant of a [`Validated`].
679///
680/// The iterator yields one value if the result is [`Good`], otherwise nothing.
681///
682/// Created by [`Validated::iter`].
683#[derive(Debug)]
684pub struct Iter<'a, T: 'a> {
685 inner: Option<&'a T>,
686}
687
688impl<'a, T> Iterator for Iter<'a, T> {
689 type Item = &'a T;
690
691 #[inline]
692 fn next(&mut self) -> Option<Self::Item> {
693 self.inner.take()
694 }
695
696 #[inline]
697 fn size_hint(&self) -> (usize, Option<usize>) {
698 let n = if self.inner.is_some() { 1 } else { 0 };
699 (n, Some(n))
700 }
701}
702
703impl<T> DoubleEndedIterator for Iter<'_, T> {
704 #[inline]
705 fn next_back(&mut self) -> Option<Self::Item> {
706 self.inner.take()
707 }
708}
709
710impl<T> ExactSizeIterator for Iter<'_, T> {}
711
712/// An iterator over a mutable reference to the [`Good`] variant of a [`Validated`].
713///
714/// Created by [`Validated::iter_mut`].
715#[derive(Debug)]
716pub struct IterMut<'a, T: 'a> {
717 inner: Option<&'a mut T>,
718}
719
720impl<'a, T> Iterator for IterMut<'a, T> {
721 type Item = &'a mut T;
722
723 #[inline]
724 fn next(&mut self) -> Option<&'a mut T> {
725 self.inner.take()
726 }
727
728 #[inline]
729 fn size_hint(&self) -> (usize, Option<usize>) {
730 let n = if self.inner.is_some() { 1 } else { 0 };
731 (n, Some(n))
732 }
733}
734
735impl<T> DoubleEndedIterator for IterMut<'_, T> {
736 #[inline]
737 fn next_back(&mut self) -> Option<Self::Item> {
738 self.inner.take()
739 }
740}
741
742impl<T> ExactSizeIterator for IterMut<'_, T> {}
743
744/// An iterator over the value in a [`Good`] variant of a [`Validated`].
745///
746/// The iterator yields one value if the result is [`Good`], otherwise nothing.
747///
748/// This struct is created by the [`into_iter`] method on
749/// [`Validated`] (provided by the [`IntoIterator`] trait).
750///
751/// [`into_iter`]: IntoIterator::into_iter
752#[derive(Clone, Debug)]
753pub struct IntoIter<T> {
754 inner: Option<T>,
755}
756
757impl<T> Iterator for IntoIter<T> {
758 type Item = T;
759
760 #[inline]
761 fn next(&mut self) -> Option<T> {
762 self.inner.take()
763 }
764
765 #[inline]
766 fn size_hint(&self) -> (usize, Option<usize>) {
767 let n = if self.inner.is_some() { 1 } else { 0 };
768 (n, Some(n))
769 }
770}
771
772/// Fuse some `NEVec`s together.
773fn nons<E, I>(mut a: NEVec<E>, rest: I) -> NEVec<E>
774where
775 I: Iterator<Item = NEVec<E>>,
776{
777 for i in rest {
778 a.extend(i);
779 }
780
781 a
782}