summaryrefslogtreecommitdiff
path: root/crates/vcs_data/src/data/local
diff options
context:
space:
mode:
author魏曹先生 <1992414357@qq.com>2025-11-22 19:39:52 +0800
committer魏曹先生 <1992414357@qq.com>2025-11-22 19:39:52 +0800
commit855258f45e593b31824016f539f716a549ae483b (patch)
tree07101141a22defe1d918540c4d590225491d1364 /crates/vcs_data/src/data/local
parentd99dfa9dd48bc876a22dc6119dde44daeac8a4e3 (diff)
Add align module for sorting file analysis results
Diffstat (limited to 'crates/vcs_data/src/data/local')
-rw-r--r--crates/vcs_data/src/data/local/align.rs107
1 files changed, 107 insertions, 0 deletions
diff --git a/crates/vcs_data/src/data/local/align.rs b/crates/vcs_data/src/data/local/align.rs
new file mode 100644
index 0000000..1b8c3c9
--- /dev/null
+++ b/crates/vcs_data/src/data/local/align.rs
@@ -0,0 +1,107 @@
+use std::{
+ collections::{HashMap, HashSet},
+ path::PathBuf,
+};
+
+use data_struct::dada_sort::quick_sort_with_cmp;
+
+use crate::data::local::file_status::AnalyzeResult;
+
+pub type AlignTasksName = String;
+pub type AlignPathBuf = PathBuf;
+pub type AlignLostPathBuf = PathBuf;
+pub type AlignCreatedPathBuf = PathBuf;
+
+pub struct AlignTasks {
+ pub created: Vec<(AlignTasksName, AlignPathBuf)>,
+ pub lost: Vec<(AlignTasksName, AlignPathBuf)>,
+ pub moved: Vec<(AlignTasksName, (AlignLostPathBuf, AlignCreatedPathBuf))>,
+}
+
+impl AlignTasks {
+ pub fn clone_from_analyze_result(result: &AnalyzeResult) -> Self {
+ AlignTasks {
+ created: path_hash_set_sort_helper(result.created.clone(), "created"),
+ lost: path_hash_set_sort_helper(result.lost.clone(), "lost"),
+ moved: path_hash_map_sort_helper(result.moved.clone(), "moved"),
+ }
+ }
+
+ pub fn from_analyze_result(result: AnalyzeResult) -> Self {
+ AlignTasks {
+ created: path_hash_set_sort_helper(result.created, "created"),
+ lost: path_hash_set_sort_helper(result.lost, "lost"),
+ moved: path_hash_map_sort_helper(result.moved, "moved"),
+ }
+ }
+}
+
+fn path_hash_set_sort_helper(
+ hash_set: HashSet<PathBuf>,
+ prefix: impl Into<String>,
+) -> Vec<(String, PathBuf)> {
+ let prefix_str = prefix.into();
+ let mut vec: Vec<(String, PathBuf)> = hash_set
+ .into_iter()
+ .map(|path| {
+ let hash = sha1_hash::calc_sha1_string(path.to_string_lossy());
+ let hash_prefix: String = hash.chars().take(8).collect();
+ let name = format!("{}:{}", prefix_str, hash_prefix);
+ (name, path)
+ })
+ .collect();
+
+ quick_sort_with_cmp(&mut vec, false, |a, b| {
+ // Compare by path depth first
+ let a_depth = a.1.components().count();
+ let b_depth = b.1.components().count();
+
+ if a_depth != b_depth {
+ return if a_depth < b_depth { -1 } else { 1 };
+ }
+
+ // If same depth, compare lexicographically
+ match a.1.cmp(&b.1) {
+ std::cmp::Ordering::Less => -1,
+ std::cmp::Ordering::Equal => 0,
+ std::cmp::Ordering::Greater => 1,
+ }
+ });
+
+ vec
+}
+
+fn path_hash_map_sort_helper(
+ hash_map: HashMap<String, (PathBuf, PathBuf)>,
+ prefix: impl Into<String>,
+) -> Vec<(String, (PathBuf, PathBuf))> {
+ let prefix_str = prefix.into();
+ let mut vec: Vec<(String, (PathBuf, PathBuf))> = hash_map
+ .into_values()
+ .map(|(path1, path2)| {
+ let hash = sha1_hash::calc_sha1_string(path1.to_string_lossy());
+ let hash_prefix: String = hash.chars().take(8).collect();
+ let name = format!("{}:{}", prefix_str, hash_prefix);
+ (name, (path1, path2))
+ })
+ .collect();
+
+ quick_sort_with_cmp(&mut vec, false, |a, b| {
+ // Compare by first PathBuf's path depth first
+ let a_depth = a.1.0.components().count();
+ let b_depth = b.1.0.components().count();
+
+ if a_depth != b_depth {
+ return if a_depth < b_depth { -1 } else { 1 };
+ }
+
+ // If same depth, compare lexicographically by first PathBuf
+ match a.1.0.cmp(&b.1.0) {
+ std::cmp::Ordering::Less => -1,
+ std::cmp::Ordering::Equal => 0,
+ std::cmp::Ordering::Greater => 1,
+ }
+ });
+
+ vec
+}