summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Oram <dev@mitmaro.ca>2022-11-09 10:01:55 -0330
committerTim Oram <dev@mitmaro.ca>2022-11-10 08:31:06 -0330
commit51112c3b059339422aa9ba0d11deab7e41fdcbe2 (patch)
tree9d251d7e9a2831bd875d0c79520947d45ca2413f
parente70dbb23694c36c41f3d95363beeb2b909faf346 (diff)
Add version tracking to todofile
-rw-r--r--Cargo.lock1
-rw-r--r--src/todo_file/Cargo.toml2
-rw-r--r--src/todo_file/src/lib.rs37
-rw-r--r--src/todo_file/src/version.rs58
4 files changed, 97 insertions, 1 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d2a508d..a42cda8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -408,6 +408,7 @@ dependencies = [
"rustc_version",
"tempfile",
"thiserror",
+ "uuid",
]
[[package]]
diff --git a/src/todo_file/Cargo.toml b/src/todo_file/Cargo.toml
index 92aad07..0c0bfe1 100644
--- a/src/todo_file/Cargo.toml
+++ b/src/todo_file/Cargo.toml
@@ -17,11 +17,13 @@ name = "todo_file"
[dependencies]
tempfile = "3.3.0"
thiserror = "1.0.37"
+uuid = { version = "1.2.1", features = ["v4", "fast-rng"] }
[dev-dependencies]
claim = { git = "https://github.com/Turbo87/rust-claim.git", rev = "23892a3" }
pretty_assertions = "1.3.0"
rstest = "0.15.0"
+tempfile = "3.3.0"
girt-testutils = {version = "0.1.0", path = "../testutils"}
[build-dependencies]
diff --git a/src/todo_file/src/lib.rs b/src/todo_file/src/lib.rs
index 0624415..0466e8e 100644
--- a/src/todo_file/src/lib.rs
+++ b/src/todo_file/src/lib.rs
@@ -120,6 +120,7 @@ mod line;
#[cfg(not(tarpaulin_include))]
pub mod testutil;
mod utils;
+mod version;
use std::{
fs::{read_to_string, File},
@@ -128,7 +129,7 @@ use std::{
slice::Iter,
};
-pub use self::{action::Action, edit_content::EditContext, line::Line};
+pub use self::{action::Action, edit_content::EditContext, line::Line, version::Version};
use self::{
history::{History, HistoryItem},
utils::{remove_range, swap_range_down, swap_range_up},
@@ -144,6 +145,7 @@ pub struct TodoFile {
is_noop: bool,
lines: Vec<Line>,
selected_line_index: usize,
+ version: Version,
}
impl TodoFile {
@@ -158,6 +160,7 @@ impl TodoFile {
lines: vec![],
is_noop: false,
selected_line_index: 0,
+ version: Version::new(),
}
}
@@ -174,6 +177,7 @@ impl TodoFile {
if self.selected_line_index >= self.lines.len() {
self.selected_line_index = if self.lines.is_empty() { 0 } else { self.lines.len() - 1 };
}
+ self.version.reset();
self.history.reset();
}
@@ -268,6 +272,7 @@ impl TodoFile {
};
swap_range_up(&mut self.lines, start, end);
+ self.version.increment();
self.history.record(HistoryItem::new_swap_up(start, end));
true
}
@@ -283,6 +288,7 @@ impl TodoFile {
}
swap_range_down(&mut self.lines, start_index, end_index);
+ self.version.increment();
self.history.record(HistoryItem::new_swap_down(start_index, end_index));
true
}
@@ -297,6 +303,7 @@ impl TodoFile {
index
};
self.lines.insert(i, line);
+ self.version.increment();
self.history.record(HistoryItem::new_add(i, i));
}
@@ -317,6 +324,7 @@ impl TodoFile {
};
let removed_lines = remove_range(&mut self.lines, start, end);
+ self.version.increment();
self.history.record(HistoryItem::new_remove(start, end, removed_lines));
}
@@ -350,21 +358,31 @@ impl TodoFile {
line.edit_content(content);
}
}
+ self.version.increment();
self.history.record(HistoryItem::new_modify(start, end, lines));
}
/// Undo the last modification.
#[inline]
pub fn undo(&mut self) -> Option<(usize, usize)> {
+ self.version.increment();
self.history.undo(&mut self.lines)
}
/// Redo the last undone modification.
#[inline]
pub fn redo(&mut self) -> Option<(usize, usize)> {
+ self.version.increment();
self.history.redo(&mut self.lines)
}
+ /// Get the current version
+ #[must_use]
+ #[inline]
+ pub const fn version(&self) -> &Version {
+ &self.version
+ }
+
/// Get the selected line.
#[must_use]
#[inline]
@@ -477,6 +495,7 @@ mod tests {
fn load_file() {
let (todo_file, _) = create_and_load_todo_file(&["pick aaa foobar"]);
assert_todo_lines!(todo_file, "pick aaa foobar");
+ assert_ne!(todo_file.version(), &Version::new());
}
#[test]
@@ -501,8 +520,10 @@ mod tests {
#[test]
fn set_lines() {
let (mut todo_file, _) = create_and_load_todo_file(&[]);
+ let old_version = todo_file.version;
todo_file.set_lines(vec![create_line("pick bbb comment")]);
assert_todo_lines!(todo_file, "pick bbb comment");
+ assert_ne!(todo_file.version(), &old_version);
}
#[test]
@@ -563,6 +584,7 @@ mod tests {
fn add_line() {
let (mut todo_file, _) =
create_and_load_todo_file(&["pick aaa comment", "drop bbb comment", "edit ccc comment"]);
+ let old_version = *todo_file.version();
todo_file.add_line(1, create_line("fixup ddd comment"));
assert_todo_lines!(
todo_file,
@@ -571,6 +593,7 @@ mod tests {
"drop bbb comment",
"edit ccc comment"
);
+ assert_ne!(todo_file.version(), &old_version);
}
#[test]
@@ -609,8 +632,10 @@ mod tests {
fn remove_lines() {
let (mut todo_file, _) =
create_and_load_todo_file(&["pick aaa comment", "drop bbb comment", "edit ccc comment"]);
+ let old_version = *todo_file.version();
todo_file.remove_lines(1, 1);
assert_todo_lines!(todo_file, "pick aaa comment", "edit ccc comment");
+ assert_ne!(todo_file.version(), &old_version);
}
#[test]
@@ -631,6 +656,7 @@ mod tests {
fn update_range_full_set_action() {
let (mut todo_file, _) =
create_and_load_todo_file(&["pick aaa comment", "drop bbb comment", "edit ccc comment"]);
+ let old_version = *todo_file.version();
todo_file.update_range(0, 2, &EditContext::new().action(Action::Reword));
assert_todo_lines!(
todo_file,
@@ -638,6 +664,7 @@ mod tests {
"reword bbb comment",
"reword ccc comment"
);
+ assert_ne!(todo_file.version(), &old_version);
}
#[test]
@@ -693,18 +720,24 @@ mod tests {
let (mut todo_file, _) =
create_and_load_todo_file(&["pick aaa comment", "drop bbb comment", "edit ccc comment"]);
todo_file.update_range(0, 0, &EditContext::new().action(Action::Drop));
+ let old_version = *todo_file.version();
let _undo_result = todo_file.undo();
assert_todo_lines!(todo_file, "pick aaa comment", "drop bbb comment", "edit ccc comment");
+ assert_ne!(todo_file.version(), &old_version);
+ let old_version = *todo_file.version();
let _ = todo_file.redo();
assert_todo_lines!(todo_file, "drop aaa comment", "drop bbb comment", "edit ccc comment");
+ assert_ne!(todo_file.version(), &old_version);
}
#[test]
fn swap_up() {
let (mut todo_file, _) =
create_and_load_todo_file(&["pick aaa comment", "pick bbb comment", "pick ccc comment"]);
+ let old_version = *todo_file.version();
assert!(todo_file.swap_range_up(1, 2));
assert_todo_lines!(todo_file, "pick bbb comment", "pick ccc comment", "pick aaa comment");
+ assert_ne!(todo_file.version(), &old_version);
}
#[test]
@@ -774,8 +807,10 @@ mod tests {
fn swap_down() {
let (mut todo_file, _) =
create_and_load_todo_file(&["pick aaa comment", "pick bbb comment", "pick ccc comment"]);
+ let old_version = *todo_file.version();
assert!(todo_file.swap_range_down(0, 1));
assert_todo_lines!(todo_file, "pick ccc comment", "pick aaa comment", "pick bbb comment");
+ assert_ne!(todo_file.version(), &old_version);
}
#[test]
diff --git a/src/todo_file/src/version.rs b/src/todo_file/src/version.rs
new file mode 100644
index 0000000..3f17a6c
--- /dev/null
+++ b/src/todo_file/src/version.rs
@@ -0,0 +1,58 @@
+use uuid::Uuid;
+
+/// Tracks the changing state of the rebase file
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct Version {
+ id: Uuid,
+ counter: u32,
+}
+
+impl Version {
+ pub(crate) fn new() -> Self {
+ Self {
+ id: Uuid::new_v4(),
+ counter: 0,
+ }
+ }
+
+ pub(crate) fn reset(&mut self) {
+ self.id = Uuid::new_v4();
+ self.counter = 0;
+ }
+
+ pub(crate) fn increment(&mut self) {
+ self.counter = self.counter.wrapping_add(1);
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn reset() {
+ let mut version = Version::new();
+ version.counter = 42;
+ let prev_id = version.id;
+ version.reset();
+ assert_ne!(version.id, prev_id);
+ assert_eq!(version.counter, 0);
+ }
+
+ #[test]
+ fn increment() {
+ let mut version = Version::new();
+ let prev_id = version.id;
+ version.increment();
+ assert_eq!(version.id, prev_id);
+ assert_eq!(version.counter, 1);
+ }
+
+ #[test]
+ fn increment_wrap() {
+ let mut version = Version::new();
+ version.counter = u32::MAX;
+ version.increment();
+ assert_eq!(version.counter, 0);
+ }
+}