From ebdb7c1d4c027de7ee2ffc2675420cd876b97237 Mon Sep 17 00:00:00 2001 From: Andrew Gallant Date: Sat, 21 Apr 2018 10:16:47 -0400 Subject: [PATCH] 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 --- ignore/src/lib.rs | 38 ++++++++++++++++++++++++++++++++++++++ ignore/src/walk.rs | 5 +++-- 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, @@ -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).