diff options
| author | Mel <einebeere@gmail.com> | 2021-09-21 01:04:49 +0200 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2021-09-21 01:05:03 +0200 |
| commit | 9e019b462ff05315641c95442faf7f8fc80f76b1 (patch) | |
| tree | 5813c85887544d865542fb122882a1fb9d2be718 /src | |
| parent | c25d22681f9bc6ddba512895182af0ce0252731b (diff) | |
| download | ka-9e019b462ff05315641c95442faf7f8fc80f76b1.tar.zst ka-9e019b462ff05315641c95442faf7f8fc80f76b1.zip | |
Slightly more consistent error handling
Diffstat (limited to 'src')
| -rw-r--r-- | src/actions/create.rs | 6 | ||||
| -rw-r--r-- | src/actions/mod.rs | 11 | ||||
| -rw-r--r-- | src/actions/shift.rs | 12 | ||||
| -rw-r--r-- | src/actions/update.rs | 14 | ||||
| -rw-r--r-- | src/files.rs | 139 | ||||
| -rw-r--r-- | src/history.rs | 17 |
6 files changed, 109 insertions, 90 deletions
diff --git a/src/actions/create.rs b/src/actions/create.rs index 26d20c8..f00e95d 100644 --- a/src/actions/create.rs +++ b/src/actions/create.rs @@ -1,10 +1,12 @@ -use std::{fs, io}; +use std::fs; + +use anyhow::Result; use crate::{actions::update, files::Locations}; use super::ActionOptions; -pub fn create(command_options: ActionOptions) -> io::Result<()> { +pub fn create(command_options: ActionOptions) -> Result<()> { let locations = Locations::from(&command_options); if locations.ka_path.exists() { diff --git a/src/actions/mod.rs b/src/actions/mod.rs index 588ce8f..86af955 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -4,6 +4,7 @@ mod update; use std::path::{Path, PathBuf}; +use anyhow::Result; pub use create::create; pub use shift::shift; pub use update::update; @@ -19,12 +20,8 @@ impl ActionOptions { } } - pub fn from_pwd() -> Result<Self, ()> { - let current_path = std::env::current_dir(); - if let Ok(repository_path) = current_path { - Ok(ActionOptions { repository_path }) - } else { - Err(()) - } + pub fn from_pwd() -> Result<Self> { + let repository_path = std::env::current_dir()?; + Ok(ActionOptions { repository_path }) } } diff --git a/src/actions/shift.rs b/src/actions/shift.rs index c02f0ed..1bd8864 100644 --- a/src/actions/shift.rs +++ b/src/actions/shift.rs @@ -1,9 +1,11 @@ use std::{ fs, - io::{self, Seek, Write}, + io::{Seek, Write}, path::Path, }; +use anyhow::Result; + use crate::{ files::{Locations, RepositoryPaths}, history::FileHistory, @@ -11,14 +13,14 @@ use crate::{ use super::ActionOptions; -pub fn shift(command_options: ActionOptions, path: &str, new_cursor: usize) -> io::Result<()> { +pub fn shift(command_options: ActionOptions, path: &str, new_cursor: usize) -> Result<()> { let locations = Locations::from(&command_options); - match RepositoryPaths::from_tracked(&locations, Path::new(path)) { + match RepositoryPaths::from_tracked(&locations, Path::new(path))? { RepositoryPaths::Tracked(tracked) => { let mut history_file = tracked.load_history_file()?; - let mut file_history = FileHistory::from_file(&mut history_file).unwrap(); + let mut file_history = FileHistory::from_file(&mut history_file)?; file_history.set_cursor(new_cursor); if file_history.file_is_deleted() { @@ -38,7 +40,7 @@ pub fn shift(command_options: ActionOptions, path: &str, new_cursor: usize) -> i RepositoryPaths::Deleted(deleted) => { let mut history_file = deleted.load_history_file()?; - let mut file_history = FileHistory::from_file(&mut history_file).unwrap(); + let mut file_history = FileHistory::from_file(&mut history_file)?; file_history.set_cursor(new_cursor); if !file_history.file_is_deleted() { diff --git a/src/actions/update.rs b/src/actions/update.rs index a2bc08d..a7d1aad 100644 --- a/src/actions/update.rs +++ b/src/actions/update.rs @@ -1,4 +1,6 @@ -use std::io::{self, Read}; +use std::io::Read; + +use anyhow::{Context, Result}; use crate::{ files::{Locations, RepositoryPaths}, @@ -8,12 +10,12 @@ use crate::{ use super::ActionOptions; -pub fn update(command_options: ActionOptions) -> io::Result<()> { +pub fn update(command_options: ActionOptions) -> Result<()> { let locations = Locations::from(&command_options); let entries = locations .get_repository_paths() - .expect("Could not traverse files."); + .context("Could not traverse files.")?; for element in entries { update_file(element, &locations)?; @@ -22,11 +24,11 @@ pub fn update(command_options: ActionOptions) -> io::Result<()> { Ok(()) } -fn update_file(paths: RepositoryPaths, locations: &Locations) -> io::Result<()> { +fn update_file(paths: RepositoryPaths, locations: &Locations) -> Result<()> { let new_state = match paths { RepositoryPaths::Deleted(deleted) => { let mut history_file = deleted.load_history_file()?; - let file_history = FileHistory::from_file(&mut history_file).unwrap(); + let file_history = FileHistory::from_file(&mut history_file)?; if !file_history.file_is_deleted() { let mut new_history = file_history; new_history.add_change(FileChange::Deleted); @@ -55,7 +57,7 @@ fn update_file(paths: RepositoryPaths, locations: &Locations) -> io::Result<()> let mut history_file = tracked.load_history_file()?; let mut tracked_file = tracked.load_tracked_file()?; - let file_history = FileHistory::from_file(&mut history_file).unwrap(); + let file_history = FileHistory::from_file(&mut history_file)?; let mut new_content = String::new(); tracked_file.read_to_string(&mut new_content)?; diff --git a/src/files.rs b/src/files.rs index 2512fa5..81bdd25 100644 --- a/src/files.rs +++ b/src/files.rs @@ -1,9 +1,11 @@ use std::{ - fs::{self, DirEntry, File, OpenOptions}, + fs::{self, DirEntry, File, OpenOptions, ReadDir}, io, path::{Path, PathBuf}, }; +use anyhow::{Context, Error, Result}; + use crate::actions::ActionOptions; pub struct Locations { @@ -13,61 +15,68 @@ pub struct Locations { } impl Locations { - pub fn get_repository_paths(&self) -> Result<Vec<RepositoryPaths>, ()> { - let repository_entries = fs::read_dir(&self.repository_path).map_err(|_| ())?; - let history_entries = fs::read_dir(&self.ka_files_path).map_err(|_| ())?; - - let tracked_paths = repository_entries - .map(Result::unwrap) - .filter(|entry| entry.path() != self.ka_path) - .flat_map(Self::flatten_directories) - .map(|entry| { - let path = entry.path(); - RepositoryPaths::from_tracked(&self, &path) - }); - - let deleted_paths = history_entries - .map(Result::unwrap) - .flat_map(Self::flatten_directories) - .filter_map(|entry| { - let path = entry.path(); - let file = RepositoryPaths::from_history(&self, &path); - match file { - RepositoryPaths::Deleted { .. } => Some(file), - RepositoryPaths::Tracked { .. } => None, - _ => unreachable!(), - } - }); + pub fn get_repository_paths(&self) -> Result<Vec<RepositoryPaths>, Error> { + let repository_entries = + fs::read_dir(&self.repository_path).context("Failed reading tracked file entries.")?; + let history_entries = + fs::read_dir(&self.ka_files_path).context("Failed reading history file entries.")?; + + let tracked_paths = Self::walk_directory(repository_entries, &|entry| { + let file_path = entry.path(); + if file_path != self.ka_path { + RepositoryPaths::from_tracked(&self, &file_path).ok() + } else { + None + } + })?; + + let deleted_paths = Self::walk_directory(history_entries, &|entry| { + let file_path = entry.path(); + let file = RepositoryPaths::from_history(&self, &file_path).ok()?; + match file { + RepositoryPaths::Deleted { .. } => Some(file), + RepositoryPaths::Tracked { .. } => None, + _ => unreachable!(), + } + })?; - let all_paths = tracked_paths.chain(deleted_paths); + let mut all_paths = tracked_paths; + all_paths.extend(deleted_paths); - Ok(all_paths.collect()) + Ok(all_paths) } - pub fn tracked_from_history(&self, history_file_path: &Path) -> PathBuf { - self.repository_path - .join(history_file_path.strip_prefix(&self.ka_files_path).unwrap()) + pub fn tracked_from_history(&self, history_file_path: &Path) -> Result<PathBuf> { + let raw_path = history_file_path.strip_prefix(&self.ka_files_path)?; + Ok(self.repository_path.join(raw_path)) } - pub fn history_from_tracked(&self, tracked_file_path: &Path) -> PathBuf { - self.ka_files_path.join( - tracked_file_path - .strip_prefix(&self.repository_path) - .unwrap(), - ) + pub fn history_from_tracked(&self, tracked_file_path: &Path) -> Result<PathBuf> { + let raw_path = tracked_file_path.strip_prefix(&self.repository_path)?; + Ok(self.ka_files_path.join(raw_path)) } - fn flatten_directories(entry: DirEntry) -> Vec<DirEntry> { - let file_type = entry.file_type().expect("Could not read a file type."); - if file_type.is_dir() { - fs::read_dir(entry.path()) - .expect("Could not read nested directory.") - .map(Result::unwrap) - .flat_map(Self::flatten_directories) - .collect() - } else { - vec![entry] + fn walk_directory( + directory: ReadDir, + filter_map: &dyn Fn(DirEntry) -> Option<RepositoryPaths>, + ) -> Result<Vec<RepositoryPaths>> { + let mut entries = Vec::new(); + + for res in directory { + let entry = res?; + let file_type = entry.file_type()?; + if file_type.is_dir() { + let nested_directory = fs::read_dir(entry.path())?; + let nested_paths = Self::walk_directory(nested_directory, filter_map)?; + entries.extend(nested_paths); + } else { + if let Some(paths) = filter_map(entry) { + entries.push(paths); + } + } } + + Ok(entries) } } @@ -91,9 +100,9 @@ pub enum RepositoryPaths { } impl RepositoryPaths { - pub fn from_history(locations: &Locations, history_file_path: &Path) -> Self { - let tracked_path = locations.tracked_from_history(history_file_path); - if !tracked_path.exists() { + pub fn from_history(locations: &Locations, history_file_path: &Path) -> Result<Self> { + let tracked_path = locations.tracked_from_history(history_file_path)?; + Ok(if !tracked_path.exists() { RepositoryPaths::Deleted(FileDeleted { history_path: history_file_path.to_path_buf(), }) @@ -102,12 +111,12 @@ impl RepositoryPaths { history_path: history_file_path.to_path_buf(), tracked_path, }) - } + }) } - pub fn from_tracked(locations: &Locations, tracked_file_path: &Path) -> Self { - let history_path = locations.history_from_tracked(tracked_file_path); - if !history_path.exists() { + pub fn from_tracked(locations: &Locations, tracked_file_path: &Path) -> Result<Self> { + let history_path = locations.history_from_tracked(tracked_file_path)?; + Ok(if !history_path.exists() { RepositoryPaths::Untracked(FileUntracked { path: tracked_file_path.to_path_buf(), }) @@ -116,7 +125,7 @@ impl RepositoryPaths { history_path, tracked_path: tracked_file_path.to_path_buf(), }) - } + }) } } @@ -132,8 +141,10 @@ impl FileDeleted { .open(&self.history_path) } - pub fn create_tracked_file(&self, locations: &Locations) -> io::Result<File> { - File::create(locations.tracked_from_history(&self.history_path)) + pub fn create_tracked_file(&self, locations: &Locations) -> Result<File> { + Ok(File::create( + locations.tracked_from_history(&self.history_path)?, + )?) } } @@ -146,16 +157,16 @@ impl FileUntracked { OpenOptions::new().read(true).open(&self.path) } - pub fn create_history_file(&self, locations: &Locations) -> io::Result<File> { - let history_path = locations.history_from_tracked(&self.path); + pub fn create_history_file(&self, locations: &Locations) -> Result<File> { + let history_path = locations.history_from_tracked(&self.path)?; - history_path.parent().map(|dir_path| { - if !dir_path.exists() { - fs::create_dir_all(dir_path).unwrap(); + if let Some(parent_path) = history_path.parent(){ + if !parent_path.exists() { + fs::create_dir_all(parent_path)?; } - }); + } - File::create(history_path) + Ok(File::create(history_path)?) } } diff --git a/src/history.rs b/src/history.rs index 25a9555..13b2838 100644 --- a/src/history.rs +++ b/src/history.rs @@ -1,7 +1,12 @@ -use std::{fs::File, io::{self, Read, Seek, Write}}; +use std::{ + fs::File, + io::{Read, Seek, Write}, +}; use serde::{Deserialize, Serialize}; +use anyhow::{Context, Result}; + use crate::text_diff::TextChange; #[derive(Serialize, Deserialize, Debug)] @@ -11,13 +16,13 @@ pub struct FileHistory { } impl FileHistory { - pub fn from_file(file: &mut File) -> Result<FileHistory, ()> { + pub fn from_file(file: &mut File) -> Result<FileHistory> { let mut buffer = Vec::new(); file.read_to_end(&mut buffer) - .expect("Could not read file history,"); + .context("Failed reading file history.")?; let file_history = serde_json::from_slice::<FileHistory>(&buffer); - Ok(file_history.expect("Corrupted file history.")) + Ok(file_history.context("Corrupted file history.")?) } pub fn cursor(&self) -> usize { @@ -48,8 +53,8 @@ impl FileHistory { buffer } - pub fn write_to_file(&self, file: &mut File) -> io::Result<()> { - let encoded: Vec<u8> = serde_json::to_vec(self).unwrap(); + pub fn write_to_file(&self, file: &mut File) -> anyhow::Result<()> { + let encoded: Vec<u8> = serde_json::to_vec(self)?; file.rewind()?; file.set_len(0)?; file.write_all(encoded.as_ref())?; |
