diff --git a/src/dotfile/dir.rs b/src/dotfile/dir.rs index 84bec29..ee14991 100644 --- a/src/dotfile/dir.rs +++ b/src/dotfile/dir.rs @@ -1,4 +1,4 @@ -use std::fs; +use std::fs::{self, DirEntry}; use std::path::PathBuf; use std::fmt; use std::error::Error; @@ -22,75 +22,79 @@ impl Directory { fs::create_dir_all(path)?; } - let dir: Vec<_> = fs::read_dir(path)?.collect(); + let entries: Vec<_> = fs::read_dir(path)?.collect(); - // Find a better way to do this sometime - let mut read_errors: Vec = Vec::new(); - let mut metadata_errors: Vec = Vec::new(); - let mut create_dir_errors: Vec = Vec::new(); - let mut create_file_errors: Vec = Vec::new(); - - let entries = dir.into_iter().filter_map(|entry| match entry { - Ok(entry) => Some(entry), - Err(e) => { - read_errors.push(DirError::from(e)); - None - } - }); - - - let valid_entries: Vec<_> = entries - .filter_map(|entry| match entry.metadata() { - Ok(_) => Some(entry), - Err(e) => { - metadata_errors.push(DirError::from(e)); - None + let entries: Vec<_> = entries + .into_iter() + .map(|entry| match entry { + Ok(entry) => match entry.metadata() { + Ok(_) => Ok(entry), + Err(e) => Err(e), + }, + Err(e) => Err(e), } - }) - .collect(); + ).collect(); + + let (valid_entries, io_errors): (Vec<_>, Vec<_>) = entries.into_iter().partition(|entry| entry.is_ok()); + + let valid_entries: Vec<_> = valid_entries.into_iter().map(|entry| entry.unwrap()).collect(); + let io_errors = io_errors.into_iter().map(|err| DirError::from(err.err().unwrap())); - let directories: Vec<_> = valid_entries - .iter() - .filter_map(|entry| - if entry.metadata().unwrap().is_dir() { - match Directory::new(&entry.path()) { - Ok(dir) => Some(dir), - Err(e) => { - create_dir_errors.push(DirError::from(e)); - None - }, - } - } else { - None - }) - .collect(); + let dirs = Directory::get_dirs(&valid_entries); + let (valid_dirs, dir_errors): (Vec<_>, Vec<_>) = dirs.into_iter().partition(|dir| dir.is_ok()); + + let directories: Vec = valid_dirs.into_iter().map(|dir| dir.unwrap()).collect(); + let dir_errors = dir_errors.into_iter().map(|err| DirError::from(err.err().unwrap())); - let files: Vec = valid_entries - .iter() - .filter_map(|entry| - if entry.metadata().unwrap().is_file() { - match File::new(&entry.path()) { - Ok(file) => Some(file), - Err(e) => { - create_file_errors.push(DirError::from(e)); - None - }, - } - } else { - None - }) - .collect(); + let files = Directory::get_files(&valid_entries); + let (valid_files, file_errors): (Vec<_>, Vec<_>) = files.into_iter().partition(|file| file.is_ok()); - // Fix sometime - let errors: Vec = read_errors.into_iter().chain(metadata_errors.into_iter().chain(create_dir_errors.into_iter().chain(create_file_errors.into_iter()))).collect(); + let files: Vec = valid_files.into_iter().map(|file| file.unwrap()).collect(); + let file_errors = file_errors.into_iter().map(|err| DirError::from(err.err().unwrap())); + let errors: Vec = io_errors.chain(dir_errors).chain(file_errors).collect(); + Ok(Directory{ files, directories, path: path.to_path_buf(), errors }) } + fn get_files(entries: &Vec) -> Vec> { + + let files: Vec<_> = entries.into_iter().filter_map(|entry| match entry.metadata() { + Ok(data) if data.is_file() => { + match File::new(&entry.path()) { + Ok(file) => Some(Ok(file)), + Err(e) => Some(Err(DirError::from(e))), + } + }, + Ok(_) => None, + Err(e) => Some(Err(DirError::from(e))), + }).collect(); + + files + } + + + fn get_dirs(entries: &Vec) -> Vec> { + + let directories: Vec<_> = entries.into_iter().filter_map(|entry| match entry.metadata() { + Ok(data) if data.is_dir() => { + match Directory::new(&entry.path()) { + Ok(dir) => Some(Ok(dir)), + Err(e) => Some(Err(DirError::from(e))), + } + }, + Ok(_) => None, + Err(e) => Some(Err(DirError::from(e))), + }).collect(); + + directories + } + + pub fn copy(&self, dest_path: &PathBuf) -> Result, DirError> { let file_copy_results: Vec<_> = self.files diff --git a/src/dotfile/file.rs b/src/dotfile/file.rs index ad1add4..313a0a7 100644 --- a/src/dotfile/file.rs +++ b/src/dotfile/file.rs @@ -17,7 +17,7 @@ impl File { let filename = match path.file_name() { Some(filename) => match filename.to_str() { Some(filename) => String::from(filename), - None => return Err(FileError::InvalidUTFError), + None => return Err(FileError::FilenameInvalidUTFError), }, None => return Err(FileError::NoFileNameError), }; @@ -43,7 +43,7 @@ impl File { pub enum FileError { CopyError(std::io::Error), NoFileNameError, - InvalidUTFError, + FilenameInvalidUTFError, } impl Error for FileError {} @@ -54,7 +54,7 @@ impl fmt::Display for FileError { FileError::CopyError(copy_error) => { write!(f, "{}", copy_error) }, - FileError::InvalidUTFError => { + FileError::FilenameInvalidUTFError => { write!(f, "Invalild UTF in filename") }, FileError::NoFileNameError => {