Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/walkdir.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett Berg <googberg@gmail.com>2018-01-31 04:24:28 +0300
committerAndrew Gallant <jamslam@gmail.com>2018-01-31 04:24:28 +0300
commitb03670ee30719163f6c074498c5d17180c883c6c (patch)
tree525db0c07db8e4ba24d1324100a1d1c79c2a3787
parent9775f531be71074bdd5bf5025365f8e6e9efb110 (diff)
errors: keep context when converting to io::Error
This commit tweaks the `From<walkdir::Error> for io::Error` implementation to always retain the current context when constructing the `io::Error`. This differs from the previous implementation in that the original raw I/O error is no longer returned. To compensate, a new method, `into_io_error`, has been added which returns the original I/O error, if one exists. We do not consider this a breaking change because the documentation for the `From` impl always stated that it existed for ergonomic reasons. Arguably, the implementation in this commit is a more faithful reflection of that documentation. This commit also clears up the public documentation surrounding the aforementioned methods.
-rw-r--r--src/lib.rs57
1 files changed, 43 insertions, 14 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 053ce1c..8808692 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1282,12 +1282,13 @@ impl<P> FilterEntry<IntoIter, P> where P: FnMut(&DirEntry) -> bool {
/// case, there is no underlying IO error.
///
/// To maintain good ergonomics, this type has a
-/// `impl From<Error> for std::io::Error` defined so that you may use an
-/// [`io::Result`] with methods in this crate if you don't care about accessing
-/// the underlying error data in a structured form.
+/// [`impl From<Error> for std::io::Error`][impl] defined which preserves the original context.
+/// This allows you to use an [`io::Result`] with methods in this crate if you don't care about
+/// accessing the underlying error data in a structured form.
///
/// [`std::io::Error`]: https://doc.rust-lang.org/stable/std/io/struct.Error.html
/// [`io::Result`]: https://doc.rust-lang.org/stable/std/io/type.Result.html
+/// [impl]: struct.Error.html#impl-From%3CError%3E
#[derive(Debug)]
pub struct Error {
depth: usize,
@@ -1346,17 +1347,19 @@ impl Error {
self.depth
}
- /// Inspect the underlying [`io::Error`] if there is one.
+ /// Inspect the original [`io::Error`] if there is one.
///
/// [`None`] is returned if the [`Error`] doesn't correspond to an
/// [`io::Error`]. This might happen, for example, when the error was
/// produced because a cycle was found in the directory tree while
/// following symbolic links.
///
- /// This method returns a borrowed value that is bound to the lifetime of
- /// the [`Error`]. To obtain an owned value, the [`From`] trait can be used
- /// instead, in which case if the [`Error`] being being converted doesn't
- /// correspond to an [`io::Error`], a new one will be created.
+ /// This method returns a borrowed value that is bound to the lifetime of the [`Error`]. To
+ /// obtain an owned value, the [`into_io_error`] can be used instead.
+ ///
+ /// > This is the original [`io::Error`] and is _not_ the same as
+ /// > [`impl From<Error> for std::io::Error`][impl] which contains additional context about the
+ /// error.
///
/// # Example
///
@@ -1400,6 +1403,8 @@ impl Error {
/// [`io::Error`]: https://doc.rust-lang.org/stable/std/io/struct.Error.html
/// [`From`]: https://doc.rust-lang.org/stable/std/convert/trait.From.html
/// [`Error`]: struct.Error.html
+ /// [`into_io_error`]: struct.Error.html#method.into_io_error
+ /// [impl]: struct.Error.html#impl-From%3CError%3E
pub fn io_error(&self) -> Option<&io::Error> {
match self.inner {
ErrorInner::Io { ref err, .. } => Some(err),
@@ -1407,6 +1412,18 @@ impl Error {
}
}
+ /// Similar to [`io_error`] except consumes self to convert to the original
+ /// [`io::Error`] if one exists.
+ ///
+ /// [`io_error`]: struct.Error.html#method.io_error
+ /// [`io::Error`]: https://doc.rust-lang.org/stable/std/io/struct.Error.html
+ pub fn into_io_error(self) -> Option<io::Error> {
+ match self.inner {
+ ErrorInner::Io { err, .. } => Some(err),
+ ErrorInner::Loop { .. } => None,
+ }
+ }
+
fn from_path(depth: usize, pb: PathBuf, err: io::Error) -> Self {
Error {
depth: depth,
@@ -1468,12 +1485,24 @@ impl fmt::Display for Error {
}
impl From<Error> for io::Error {
- fn from(err: Error) -> io::Error {
- match err {
- Error { inner: ErrorInner::Io { err, .. }, .. } => err,
- err @ Error { inner: ErrorInner::Loop { .. }, .. } => {
- io::Error::new(io::ErrorKind::Other, err)
+ /// Convert the [`Error`] to an [`io::Error`], preserving the original [`Error`] as the ["inner
+ /// error"]. Note that this also makes the display of the error include the context.
+ ///
+ /// This is different from [`into_io_error`] which returns the original [`io::Error`].
+ ///
+ /// [`Error`]: struct.Error.html
+ /// [`io::Error`]: https://doc.rust-lang.org/stable/std/io/struct.Error.html
+ /// ["inner error"]: https://doc.rust-lang.org/std/io/struct.Error.html#method.into_inner
+ /// [`into_io_error`]: struct.WalkDir.html#method.into_io_error
+ fn from(walk_err: Error) -> io::Error {
+ let kind = match walk_err {
+ Error { inner: ErrorInner::Io { ref err, .. }, .. } => {
+ err.kind()
}
- }
+ Error { inner: ErrorInner::Loop { .. }, .. } => {
+ io::ErrorKind::Other
+ }
+ };
+ io::Error::new(kind, walk_err)
}
}