To do this ErrorIterator needs a Display impl, which could require making it a wrapper over Box<dyn Iterator<Item = ValidationError<'a>> + Sync + Send + 'a>, rather than just a type alias (a mild breaking change).
This will allow throwing this error to dyn Error or anyhow without any manual mapping. This impl should probably just print a list of all errors, like the examples show. Roughly:
type ErrorIterTy<'a> = Box<dyn Iterator<Item = ValidationError<'a>> + Sync + Send + 'a>;
pub struct ErrorIterator<'a>(ErrorIterTy<'a>);
impl<'a> IntoIterator for ErrorIterator<'a> {
type Item = ValidationError<'a>;
type IntoIter: ErrorIterTy<'a>;
fn into_iter(self) -> Self::IntoIter {
self.0
}
}
impl fmt::Display for ErrorIterator {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
writeln!(f, "Validation errors:");
for (idx, e) in self.enumerate() {
writeln!(f, "{idx:02}: {e}")?;
}
Ok(())
}
}
impl core::error::Error for ErrorIterator {}
To do this
ErrorIterator
needs aDisplay
impl, which could require making it a wrapper overBox<dyn Iterator<Item = ValidationError<'a>> + Sync + Send + 'a>
, rather than just a type alias (a mild breaking change).This will allow throwing this error to
dyn Error
oranyhow
without any manual mapping. This impl should probably just print a list of all errors, like the examples show. Roughly: