aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actions/create.rs6
-rw-r--r--src/actions/mod.rs11
-rw-r--r--src/actions/shift.rs12
-rw-r--r--src/actions/update.rs14
-rw-r--r--src/files.rs135
-rw-r--r--src/history.rs17
6 files changed, 107 insertions, 88 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(|_| ())?;
+ 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 = 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 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 = 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!(),
- }
- });
+ 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())?;