kutil_std/error/
errors.rs

1use super::recipient::*;
2
3use std::{error::*, fmt, iter::*, slice, vec};
4
5//
6// Errors
7//
8
9/// An [Error] that contains zero or more errors.
10///
11/// Implements [ErrorRecipient] by accumulating errors.
12#[derive(Clone, Debug)]
13pub struct Errors<ErrorT> {
14    /// The errors.
15    pub errors: Vec<ErrorT>,
16}
17
18impl<ErrorT> Errors<ErrorT> {
19    /// Constructor.
20    pub fn new() -> Self {
21        Self { errors: Vec::new() }
22    }
23
24    /// True if there are no errors.
25    pub fn is_empty(&self) -> bool {
26        self.errors.is_empty()
27    }
28
29    /// Fails with self if there are errors.
30    pub fn check(&self) -> Result<(), &Self> {
31        if self.is_empty() { Ok(()) } else { Err(self) }
32    }
33}
34
35impl<ErrorT> ErrorRecipient<ErrorT> for Errors<ErrorT> {
36    fn give(&mut self, error: impl Into<ErrorT>) -> Result<(), ErrorT> {
37        self.errors.push(error.into());
38        Ok(())
39    }
40}
41
42impl<ErrorT> Error for Errors<ErrorT> where ErrorT: Error {}
43
44impl<ErrorT> fmt::Display for Errors<ErrorT>
45where
46    ErrorT: fmt::Display,
47{
48    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
49        let mut iterator = self.errors.iter().peekable();
50        while let Some(error) = iterator.next() {
51            fmt::Display::fmt(error, formatter)?;
52            if iterator.peek().is_some() {
53                writeln!(formatter)?;
54            }
55        }
56        Ok(())
57    }
58}
59
60// Delegated
61
62impl<ErrorT> IntoIterator for Errors<ErrorT> {
63    type Item = ErrorT;
64    type IntoIter = vec::IntoIter<Self::Item>;
65
66    fn into_iter(self) -> Self::IntoIter {
67        self.errors.into_iter()
68    }
69}
70
71impl<'own, ErrorT> IntoIterator for &'own Errors<ErrorT> {
72    type Item = &'own ErrorT;
73    type IntoIter = slice::Iter<'own, ErrorT>;
74
75    fn into_iter(self) -> Self::IntoIter {
76        self.errors.iter()
77    }
78}
79
80impl<'own, ErrorT> IntoIterator for &'own mut Errors<ErrorT> {
81    type Item = &'own mut ErrorT;
82    type IntoIter = slice::IterMut<'own, ErrorT>;
83
84    fn into_iter(self) -> Self::IntoIter {
85        self.errors.iter_mut()
86    }
87}
88
89// Conversions
90
91impl<ErrorT> From<ErrorT> for Errors<ErrorT> {
92    fn from(value: ErrorT) -> Self {
93        let mut errors = Errors::new();
94        errors.errors.push(value);
95        errors
96    }
97}
98
99impl<ErrorT> Into<Vec<ErrorT>> for Errors<ErrorT> {
100    fn into(self) -> Vec<ErrorT> {
101        self.errors
102    }
103}
104
105//
106// AsErrorsResult
107//
108
109/// Converts to a [Result] with [Errors].
110pub trait AsErrorsResult<OkT, ErrorT> {
111    /// Convert to a [Result] with [Errors].
112    fn as_errors(self) -> Result<OkT, Errors<ErrorT>>;
113
114    /// If there is an error then gives it and returns the default value.
115    fn give_or<E, ErrorRecipientT>(self, default: OkT, errors: &mut ErrorRecipientT) -> Result<OkT, E>
116    where
117        ErrorT: Into<E>,
118        ErrorRecipientT: ErrorRecipient<E>;
119}
120
121impl<OkT, ErrorT> AsErrorsResult<OkT, ErrorT> for Result<OkT, ErrorT> {
122    fn as_errors(self) -> Result<OkT, Errors<ErrorT>> {
123        Ok(self?)
124    }
125
126    fn give_or<IntoErrorT, ErrorRecipientT>(self, default: OkT, errors: &mut ErrorRecipientT) -> Result<OkT, IntoErrorT>
127    where
128        ErrorT: Into<IntoErrorT>,
129        ErrorRecipientT: ErrorRecipient<IntoErrorT>,
130    {
131        match self {
132            Ok(ok) => Ok(ok),
133            Err(error) => {
134                errors.give(error.into())?;
135                Ok(default)
136            }
137        }
138    }
139}