Add ErrSpan extension trait for Result (#12626)

# Description
This adds an extension trait to `Result` that wraps errors in `Spanned`,
saving the effort of calling `.map_err(|err| err.into_spanned(span))`
every time. This will hopefully make it even more likely that someone
will want to use a spanned `io::Error` and make it easier to remove the
impl for `From<io::Error> for ShellError` because that doesn't have span
information.
This commit is contained in:
Devyn Cairns
2024-04-23 01:39:55 -07:00
committed by GitHub
parent b0acc1d890
commit 5c7f7883c8
10 changed files with 47 additions and 21 deletions

View File

@ -147,3 +147,34 @@ pub fn span(spans: &[Span]) -> Span {
Span::new(spans[0].start, end)
}
}
/// An extension trait for `Result`, which adds a span to the error type.
pub trait ErrSpan {
type Result;
/// Add the given span to the error type `E`, turning it into a `Spanned<E>`.
///
/// Some auto-conversion methods to `ShellError` from other error types are available on spanned
/// errors, to give users better information about where an error came from. For example, it is
/// preferred when working with `std::io::Error`:
///
/// ```no_run
/// use nu_protocol::{ErrSpan, ShellError, Span};
/// use std::io::Read;
///
/// fn read_from(mut reader: impl Read, span: Span) -> Result<Vec<u8>, ShellError> {
/// let mut vec = vec![];
/// reader.read_to_end(&mut vec).err_span(span)?;
/// Ok(vec)
/// }
/// ```
fn err_span(self, span: Span) -> Self::Result;
}
impl<T, E> ErrSpan for Result<T, E> {
type Result = Result<T, Spanned<E>>;
fn err_span(self, span: Span) -> Self::Result {
self.map_err(|err| err.into_spanned(span))
}
}