summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Gallant <jamslam@gmail.com>2018-04-21 10:16:47 -0400
committerAndrew Gallant <jamslam@gmail.com>2018-04-21 12:01:11 -0400
commitebdb7c1d4c027de7ee2ffc2675420cd876b97237 (patch)
tree4dc97556a2dfedd141f6f193fecb20d91eb3cb80
parent58bd0c67da542cdeb369b3af90181b902c1c2c0d (diff)
ignore: impl Clone for DirEntry
There is a small hiccup here in that a `DirEntry` can embed errors associated with reading an ignore file, which can be accessed and logged by consumers if desired. That error type can contain an io::Error, which isn't cloneable. We therefore implement Clone on our library's error type in a way that re-creates the I/O error as best as possible. Fixes #891
-rw-r--r--ignore/src/lib.rs38
-rw-r--r--ignore/src/walk.rs5
2 files changed, 41 insertions, 2 deletions
diff --git a/ignore/src/lib.rs b/ignore/src/lib.rs
index a578487c..b97e267a 100644
--- a/ignore/src/lib.rs
+++ b/ignore/src/lib.rs
@@ -132,6 +132,44 @@ pub enum Error {
InvalidDefinition,
}
+impl Clone for Error {
+ fn clone(&self) -> Error {
+ match *self {
+ Error::Partial(ref errs) => Error::Partial(errs.clone()),
+ Error::WithLineNumber { line, ref err } => {
+ Error::WithLineNumber { line: line, err: err.clone() }
+ }
+ Error::WithPath { ref path, ref err } => {
+ Error::WithPath { path: path.clone(), err: err.clone() }
+ }
+ Error::WithDepth { depth, ref err } => {
+ Error::WithDepth { depth: depth, err: err.clone() }
+ }
+ Error::Loop { ref ancestor, ref child } => {
+ Error::Loop {
+ ancestor: ancestor.clone(),
+ child: child.clone()
+ }
+ }
+ Error::Io(ref err) => {
+ match err.raw_os_error() {
+ Some(e) => Error::Io(io::Error::from_raw_os_error(e)),
+ None => {
+ Error::Io(io::Error::new(err.kind(), err.to_string()))
+ }
+ }
+ }
+ Error::Glob { ref glob, ref err } => {
+ Error::Glob { glob: glob.clone(), err: err.clone() }
+ }
+ Error::UnrecognizedFileType(ref err) => {
+ Error::UnrecognizedFileType(err.clone())
+ }
+ Error::InvalidDefinition => Error::InvalidDefinition,
+ }
+ }
+}
+
impl Error {
/// Returns true if this is a partial error.
///
diff --git a/ignore/src/walk.rs b/ignore/src/walk.rs
index c185a288..74a37f53 100644
--- a/ignore/src/walk.rs
+++ b/ignore/src/walk.rs
@@ -24,7 +24,7 @@ use {Error, PartialErrorBuilder};
///
/// The error typically refers to a problem parsing ignore files in a
/// particular directory.
-#[derive(Debug)]
+#[derive(Clone, Debug)]
pub struct DirEntry {
dent: DirEntryInner,
err: Option<Error>,
@@ -126,7 +126,7 @@ impl DirEntry {
///
/// Specifically, (3) has to essentially re-create the DirEntry implementation
/// from WalkDir.
-#[derive(Debug)]
+#[derive(Clone, Debug)]
enum DirEntryInner {
Stdin,
Walkdir(walkdir::DirEntry),
@@ -235,6 +235,7 @@ impl DirEntryInner {
/// DirEntryRaw is essentially copied from the walkdir crate so that we can
/// build `DirEntry`s from whole cloth in the parallel iterator.
+#[derive(Clone)]
struct DirEntryRaw {
/// The path as reported by the `fs::ReadDir` iterator (even if it's a
/// symbolic link).