mirror of
https://github.com/MrBeanCpp/MIT.git
synced 2026-02-11 22:26:02 +08:00
添加PathExt Trait,简化Path使用
This commit is contained in:
@@ -5,7 +5,7 @@ use colored::Colorize;
|
||||
use crate::commands::status;
|
||||
use crate::models::index::FileMetaData;
|
||||
use crate::models::*;
|
||||
use crate::utils::util;
|
||||
use crate::utils::{util, PathExt};
|
||||
|
||||
/// add是对index的操作,不会对工作区产生影响
|
||||
/// @see <a href="https://juejin.cn/post/7053831273277554696">git add .,git add -A,git add -u,git add * 的区别与联系</a>
|
||||
@@ -41,7 +41,7 @@ pub fn add(raw_paths: Vec<String>, all: bool, mut update: bool) {
|
||||
|
||||
fn add_a_file(file: &Path, index: &mut Index) {
|
||||
let workdir = util::get_working_dir().unwrap();
|
||||
if !util::is_sub_path(file, &workdir) {
|
||||
if !file.is_sub_to(&workdir) {
|
||||
//文件不在工作区内
|
||||
println!("fatal: '{}' is outside workdir at '{}'", file.display(), workdir.display());
|
||||
return;
|
||||
@@ -52,7 +52,7 @@ fn add_a_file(file: &Path, index: &mut Index) {
|
||||
return;
|
||||
}
|
||||
|
||||
let rel_path = util::to_cur_relative_path(file);
|
||||
let rel_path = file.to_relative();
|
||||
if !file.exists() {
|
||||
//文件被删除
|
||||
index.remove(file);
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{
|
||||
|
||||
use crate::{
|
||||
models::*,
|
||||
utils::{util, Store},
|
||||
utils::{util, PathExt, Store},
|
||||
};
|
||||
|
||||
/// 统计[工作区]中相对于target_blobs已删除的文件(根据filters进行过滤)
|
||||
@@ -18,7 +18,7 @@ fn get_worktree_deleted_files_in_filters(
|
||||
.iter()
|
||||
.filter(|(path, _)| {
|
||||
assert!(path.is_absolute()); //
|
||||
!path.exists() && util::include_in_paths(path, filters)
|
||||
!path.exists() && path.include_in(filters)
|
||||
})
|
||||
.map(|(path, _)| path.clone())
|
||||
.collect() //HashSet自动去重
|
||||
@@ -34,7 +34,7 @@ fn get_index_deleted_files_in_filters(
|
||||
.iter()
|
||||
.filter(|(path, _)| {
|
||||
assert!(path.is_absolute());
|
||||
!index.contains(path) && util::include_in_paths(path, filters)
|
||||
!index.contains(path) && path.include_in(filters)
|
||||
})
|
||||
.map(|(path, _)| path.clone())
|
||||
.collect() //HashSet自动去重
|
||||
@@ -53,7 +53,7 @@ fn preprocess_filters(filters: Option<&Vec<PathBuf>>) -> Vec<PathBuf> {
|
||||
fn preprocess_blobs(blobs: &Vec<(PathBuf, Hash)>) -> HashMap<PathBuf, Hash> {
|
||||
blobs // 转为绝对路径 //TODO tree改变路径表示方式后,这里需要修改
|
||||
.iter()
|
||||
.map(|(path, hash)| (util::to_workdir_absolute_path(path), hash.clone()))
|
||||
.map(|(path, hash)| (path.to_absolute_workdir(), hash.clone()))
|
||||
.collect() //to HashMap
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::utils::PathExt;
|
||||
use crate::{
|
||||
models::{head, Commit, Index},
|
||||
utils::util,
|
||||
@@ -45,7 +46,7 @@ impl Changes {
|
||||
[&mut change.new, &mut change.modified, &mut change.deleted]
|
||||
.iter_mut()
|
||||
.for_each(|paths| {
|
||||
**paths = util::map(&**paths, |p| util::to_workdir_absolute_path(p));
|
||||
**paths = util::map(&**paths, |p| p.to_absolute_workdir());
|
||||
});
|
||||
change
|
||||
}
|
||||
@@ -53,11 +54,10 @@ impl Changes {
|
||||
/// 转换为相对路径(to cur_dir)注意:要先转换为绝对路径
|
||||
fn to_relative(&self) -> Changes {
|
||||
let mut change = self.clone();
|
||||
let cur_dir = util::cur_dir();
|
||||
[&mut change.new, &mut change.modified, &mut change.deleted]
|
||||
.iter_mut()
|
||||
.for_each(|paths| {
|
||||
**paths = util::map(&**paths, |p| util::get_relative_path(p, &cur_dir));
|
||||
**paths = util::map(&**paths, |p| p.to_relative());
|
||||
});
|
||||
change
|
||||
}
|
||||
@@ -73,7 +73,7 @@ pub fn changes_to_be_committed() -> Changes {
|
||||
let tracked_files = index
|
||||
.get_tracked_files()
|
||||
.iter()
|
||||
.map(|f| util::to_workdir_relative_path(f))
|
||||
.map(|f| f.to_relative_workdir())
|
||||
.collect::<Vec<PathBuf>>();
|
||||
if head_hash == "" {
|
||||
// 初始提交
|
||||
@@ -89,7 +89,7 @@ pub fn changes_to_be_committed() -> Changes {
|
||||
for (tree_file, blob_hash) in tree_files.iter() {
|
||||
let index_file = index_files.iter().find(|&f| f == tree_file);
|
||||
if let Some(index_file) = index_file {
|
||||
let index_path = util::to_workdir_absolute_path(index_file);
|
||||
let index_path = index_file.to_absolute_workdir();
|
||||
if !index.verify_hash(&index_path, blob_hash) {
|
||||
change.modified.push(tree_file.clone());
|
||||
}
|
||||
@@ -112,11 +112,11 @@ pub fn changes_to_be_staged() -> Changes {
|
||||
let index = Index::get_instance();
|
||||
for file in index.get_tracked_files() {
|
||||
if !file.exists() {
|
||||
change.deleted.push(util::to_workdir_relative_path(&file));
|
||||
change.deleted.push(file.to_relative_workdir());
|
||||
} else if index.is_modified(&file) {
|
||||
// 若文件元数据被修改,才需要比较暂存区与文件的hash来判别内容修改
|
||||
if !index.verify_hash(&file, &util::calc_file_hash(&file)) {
|
||||
change.modified.push(util::to_workdir_relative_path(&file));
|
||||
change.modified.push(file.to_relative_workdir());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -124,7 +124,7 @@ pub fn changes_to_be_staged() -> Changes {
|
||||
for file in files {
|
||||
if !index.tracked(&file) {
|
||||
//文件未被跟踪
|
||||
change.new.push(util::to_workdir_relative_path(&file));
|
||||
change.new.push(file.to_relative_workdir());
|
||||
}
|
||||
}
|
||||
change
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::utils::PathExt;
|
||||
use crate::{models::*, utils::util};
|
||||
use once_cell::unsync::Lazy;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -76,7 +77,7 @@ impl Index {
|
||||
|
||||
/// 预处理路径,统一形式为绝对路径
|
||||
fn preprocess(path: &Path) -> PathBuf {
|
||||
util::get_absolute_path(&path)
|
||||
path.to_absolute()
|
||||
}
|
||||
|
||||
// 添加文件
|
||||
@@ -173,7 +174,7 @@ impl Index {
|
||||
.entries
|
||||
.iter()
|
||||
.map(|(path, value)| {
|
||||
let relative_path = util::get_relative_path(path, &self.working_dir);
|
||||
let relative_path = util::get_relative_path_to_dir(path, &self.working_dir);
|
||||
(relative_path, value.clone())
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::{collections::HashSet, path::PathBuf};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::utils::{util, Store};
|
||||
use crate::utils::{util, PathExt, Store};
|
||||
|
||||
use super::{Hash, Index};
|
||||
/*Tree
|
||||
@@ -41,7 +41,7 @@ fn store_path_to_tree(index: &Index, current_root: PathBuf) -> Tree {
|
||||
let path_entries: Vec<PathBuf> = index
|
||||
.get_tracked_files()
|
||||
.iter()
|
||||
.map(|file| util::to_workdir_relative_path(file))
|
||||
.map(|file| file.to_relative_workdir())
|
||||
.filter(|path| path.starts_with(¤t_root))
|
||||
.collect();
|
||||
for path in path_entries.iter() {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
pub mod store;
|
||||
pub use store::Store;
|
||||
pub mod path_ext;
|
||||
pub use path_ext::PathExt;
|
||||
pub mod test;
|
||||
pub mod util;
|
||||
|
||||
56
src/utils/path_ext.rs
Normal file
56
src/utils/path_ext.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
use crate::utils::util;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
/**
|
||||
Path的扩展 基于util 为了解耦,不要再util中使用PathExt
|
||||
*/
|
||||
pub trait PathExt {
|
||||
fn to_absolute(&self) -> PathBuf;
|
||||
fn to_absolute_workdir(&self) -> PathBuf;
|
||||
fn to_relative(&self) -> PathBuf;
|
||||
fn to_relative_workdir(&self) -> PathBuf;
|
||||
fn is_sub_to(&self, parent: &PathBuf) -> bool;
|
||||
fn include_in<T, U>(&self, paths: U) -> bool
|
||||
where
|
||||
T: AsRef<Path>,
|
||||
U: IntoIterator<Item = T>;
|
||||
}
|
||||
/*
|
||||
在 Rust 中,当你调用一个方法时,Rust 会尝试自动解引用和自动引用(auto-deref and auto-ref)来匹配方法签名。
|
||||
如果有一个为 Path 实现的方法,你可以在 PathBuf、&PathBuf、&&PathBuf 等上调用这个方法,Rust 会自动进行必要的解引用。
|
||||
*/
|
||||
impl PathExt for Path {
|
||||
/// 转换为绝对路径
|
||||
fn to_absolute(&self) -> PathBuf {
|
||||
util::get_absolute_path(&self)
|
||||
}
|
||||
|
||||
/// 转换为绝对路径(from workdir相对路径)
|
||||
fn to_absolute_workdir(&self) -> PathBuf {
|
||||
util::to_workdir_absolute_path(&self)
|
||||
}
|
||||
|
||||
/// 转换为相对路径(to cur_dir)
|
||||
fn to_relative(&self) -> PathBuf {
|
||||
util::get_relative_path(&self)
|
||||
}
|
||||
|
||||
/// 转换为相对路径(to workdir)
|
||||
fn to_relative_workdir(&self) -> PathBuf {
|
||||
util::to_workdir_relative_path(&self)
|
||||
}
|
||||
|
||||
/// 从字符串角度判断path是否是parent的子路径(不检测存在性)
|
||||
fn is_sub_to(&self, parent: &PathBuf) -> bool {
|
||||
util::is_sub_path(&self, parent)
|
||||
}
|
||||
|
||||
/// 判断是否在paths中(包括子目录),不检查存在
|
||||
fn include_in<T, U>(&self, paths: U) -> bool
|
||||
where
|
||||
T: AsRef<Path>,
|
||||
U: IntoIterator<Item = T>,
|
||||
{
|
||||
util::include_in_paths(&self, paths)
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ pub fn is_sub_path(path: &Path, parent: &Path) -> bool {
|
||||
is_parent_dir(path, parent)
|
||||
}
|
||||
|
||||
/// 判断文件是否在paths中(包括子目录),不检查存在性
|
||||
/// 判断是否在paths中(包括子目录),不检查存在性
|
||||
pub fn include_in_paths<T, U>(path: &Path, paths: U) -> bool
|
||||
where
|
||||
T: AsRef<Path>,
|
||||
@@ -252,7 +252,7 @@ pub fn list_workdir_files() -> Vec<PathBuf> {
|
||||
}
|
||||
|
||||
/// 获取相对于dir的 规范化 相对路径(不包含../ ./)
|
||||
pub fn get_relative_path(path: &Path, dir: &Path) -> PathBuf {
|
||||
pub fn get_relative_path_to_dir(path: &Path, dir: &Path) -> PathBuf {
|
||||
// 先统一为绝对路径
|
||||
let abs_path = if path.is_relative() {
|
||||
get_absolute_path(path)
|
||||
@@ -287,12 +287,12 @@ pub fn get_common_dir(p1: &Path, p2: &Path) -> PathBuf {
|
||||
|
||||
/// 获取相较于工作区(Working Dir)的相对路径
|
||||
pub fn to_workdir_relative_path(path: &Path) -> PathBuf {
|
||||
get_relative_path(path, &get_working_dir().unwrap())
|
||||
get_relative_path_to_dir(path, &get_working_dir().unwrap())
|
||||
}
|
||||
|
||||
/// 获取相较于当前目录的 规范化 相对路径(不包含../ ./)
|
||||
pub fn to_cur_relative_path(path: &Path) -> PathBuf {
|
||||
get_relative_path(path, &cur_dir())
|
||||
pub fn get_relative_path(path: &Path) -> PathBuf {
|
||||
get_relative_path_to_dir(path, &cur_dir())
|
||||
}
|
||||
|
||||
/// 获取相较于工作区(Working Dir)的绝对路径
|
||||
@@ -336,7 +336,7 @@ pub fn get_file_mode(path: &Path) -> String {
|
||||
|
||||
/// 获取绝对路径(相对于目录current_dir) 不论是否存在
|
||||
pub fn get_absolute_path(path: &Path) -> PathBuf {
|
||||
get_absolute_path_to_dir(path, &std::env::current_dir().unwrap())
|
||||
get_absolute_path_to_dir(path, &cur_dir())
|
||||
}
|
||||
|
||||
/// 获取绝对路径(相对于目录dir) 不论是否存在
|
||||
@@ -467,7 +467,7 @@ mod tests {
|
||||
fn test_get_relative_path() {
|
||||
test::setup_with_clean_mit();
|
||||
let path = Path::new("../../src\\main.rs");
|
||||
let rel_path = get_relative_path(&path, &cur_dir());
|
||||
let rel_path = get_relative_path_to_dir(&path, &cur_dir());
|
||||
println!("{:?}", rel_path);
|
||||
|
||||
assert_eq!(rel_path, path);
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
|
||||
Reference in New Issue
Block a user