From 65b39f28db7a17c56e1a3c8d08fc262165f2d384 Mon Sep 17 00:00:00 2001 From: Ethan Simmons Date: Sun, 4 Feb 2024 15:59:37 -0600 Subject: [PATCH] More error handling --- src/dotfile/dot.rs | 30 ++++++++++++++++++++++++++++++ src/fs/dir.rs | 28 +++++++--------------------- src/fs/file.rs | 15 ++++++++++++++- src/lib.rs | 19 +++++++++++++++++++ 4 files changed, 70 insertions(+), 22 deletions(-) diff --git a/src/dotfile/dot.rs b/src/dotfile/dot.rs index 389a9e1..d747e09 100644 --- a/src/dotfile/dot.rs +++ b/src/dotfile/dot.rs @@ -74,6 +74,36 @@ impl ManagedDotfile { } + pub fn get_dotfile_dir_errors(&self) -> Vec<&dir::DirError> { + + let manager_errors = if let Dotfile::Dir(dir) = &self.manager_dotfile { + Some(dir.errors.iter()) + } else { + None + }; + + let system_errors = if let Dotfile::Dir(dir) = &self.system_dotfile { + Some(dir.errors.iter()) + } else { + None + }; + + let mut errors = Vec::new(); + + match manager_errors { + Some(e) => e.for_each(|error| errors.push(error)), + None => (), + } + + match system_errors { + Some(e) => e.for_each(|error| errors.push(error)), + None => (), + } + + errors + } + + pub fn copy_dotfile(&self, to_sys: bool) -> Result, DotfileError> { let (current, destination) = if to_sys { diff --git a/src/fs/dir.rs b/src/fs/dir.rs index 52ee61e..6457eb6 100644 --- a/src/fs/dir.rs +++ b/src/fs/dir.rs @@ -22,39 +22,25 @@ impl Directory { fs::create_dir_all(path)?; } - let entries: Vec<_> = fs::read_dir(path)?.collect(); - - 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(); - - 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 entries = fs::read_dir(path)?; + let (valid_entries, io_errors): (Vec<_>, Vec<_>) = entries.partition(|entry| entry.is_ok()); + let valid_entries: Vec = valid_entries.into_iter().map(|entry| entry.unwrap()).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 = Directory::get_files(&valid_entries); let (valid_files, file_errors): (Vec<_>, Vec<_>) = files.into_iter().partition(|file| file.is_ok()); - 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 dir_errors = dir_errors.into_iter().map(|err| DirError::from(err.err().unwrap())); + let io_errors = io_errors.into_iter().map(|err| DirError::from(err.err().unwrap())); + 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 }) diff --git a/src/fs/file.rs b/src/fs/file.rs index 313a0a7..7068d85 100644 --- a/src/fs/file.rs +++ b/src/fs/file.rs @@ -14,6 +14,15 @@ pub struct File { impl File { pub fn new(path: &PathBuf) -> Result { + let parent_dir = match path.parent() { + Some(parent) => parent, + None => return Err(FileError::NoParentDirError), + }; + + if !parent_dir.exists() { + fs::create_dir_all(parent_dir)?; + } + let filename = match path.file_name() { Some(filename) => match filename.to_str() { Some(filename) => String::from(filename), @@ -43,6 +52,7 @@ impl File { pub enum FileError { CopyError(std::io::Error), NoFileNameError, + NoParentDirError, FilenameInvalidUTFError, } @@ -57,9 +67,12 @@ impl fmt::Display for FileError { FileError::FilenameInvalidUTFError => { write!(f, "Invalild UTF in filename") }, + FileError::NoParentDirError => { + write!(f, "File does not have a parent directory") + } FileError::NoFileNameError => { write!(f, "File does not have a valid filename") - } + }, } } } diff --git a/src/lib.rs b/src/lib.rs index 0f4ffa0..cb8e8ce 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,6 +26,25 @@ pub fn run(args: ArgMatches, config: cfg::Config) -> Result<(), ManagerError> { }, }).collect(); + let errored_dotfiles = valid_dotfiles.iter().filter_map(|dotfile| match dotfile.get_dotfile_dir_errors() { + errors if !errors.is_empty() => Some(dotfile), + _ => None + }); + + let _ = errored_dotfiles.map(|dotfile| { + if let dot::Dotfile::Dir(manager_dotfile) = &dotfile.manager_dotfile { + println!("Error copying dotfile: {}", manager_dotfile.path.to_str()?); + manager_dotfile.errors.iter().for_each(|error| println!("Error: {:?}", error)); + }; + + if let dot::Dotfile::Dir(system_dotfile) = &dotfile.system_dotfile { + println!("Error copying dotfile: {}", system_dotfile.path.to_str()?); + system_dotfile.errors.iter().for_each(|error| println!("Error: {:?}", error)); + }; + + Some(()) + }); + let copy_results = valid_dotfiles.iter().map(|dotfile| (dotfile.copy_dotfile(copy_to_sys), dotfile)); copy_results.for_each(|result| {