Skip to content

Commit

Permalink
fix all and release
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikachu2333 authored Dec 25, 2024
1 parent dbfd8da commit 1e240f8
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 47 deletions.
13 changes: 5 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
[package]
name = "name_exchanger_rs"
version = "1.6.0"
name = "name_exchanger_rs"
version = "2.0.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
crate-type = ["cdylib"]
#crate-type = ["staticlib"]
name = "name_exchanger_rs"

[profile.release]
lto = true
lto = true
codegen-units = 1
opt-level = "z"
strip = true
opt-level = "z"
strip = true

[dependencies]
10 changes: 5 additions & 5 deletions src/file_rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl NameExchange {
}

///改名具体执行部分
pub fn rename_each(&self, is_nested: bool, file1_first: bool) -> u8 {
pub fn rename_each(&self, is_nested: bool, file1_first: bool) -> i32 {
let mut path1 = self.f2.exchange.original_path.clone();
let mut final_name1 = self.f2.exchange.new_path.clone();
let mut path2 = self.f1.exchange.original_path.clone();
Expand All @@ -93,13 +93,13 @@ impl NameExchange {
tmp_name2 = self.f2.exchange.pre_path.clone();
}

let get_err_or_ok = |x: io::Result<()>| -> u8 {
let get_err_or_ok = |x: io::Result<()>| -> i32 {
match x {
Ok(_) => 0,
Err(x) => match x.kind() {
io::ErrorKind::PermissionDenied => 3,
io::ErrorKind::AlreadyExists => 4,
_ => 255,
io::ErrorKind::PermissionDenied => return 2_i32,
io::ErrorKind::AlreadyExists => return 3_i32,
_ => return 255_i32,
},
}
};
Expand Down
103 changes: 75 additions & 28 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::ffi::{c_char, CStr};
use std::path::PathBuf;
use std::{
ffi::{c_char, CStr},
path::PathBuf,
};

use file_rename::NameExchange;
use path_checkout::GetPathInfo;
Expand All @@ -8,42 +10,46 @@ mod path_checkout;

#[no_mangle]
/// # Safety
/// 最终暴露的执行函数
pub unsafe extern "C" fn exchange(path1: *const c_char, path2: *const c_char) -> u8 {
/// 最终暴露的执行函数,传入两个路径String,返回一个u8
///
/// 0 => Success,1 => No Exist
///
/// 2 => Permission Denied,3 => New File Already Exists
///
/// 255 => UNKNOWN ERROR
pub extern "C" fn exchange(path1: *const c_char, path2: *const c_char) -> i32 {
let binding = std::env::current_exe().unwrap();
let exe_dir = binding.parent().unwrap();

let path1 = unsafe { CStr::from_ptr(path1).to_str().unwrap().to_owned() };
let path2 = unsafe { CStr::from_ptr(path2) }
.to_str()
.unwrap()
.to_owned();
let transformer = |s: *const c_char| unsafe { CStr::from_ptr(s) }.to_string_lossy().to_string();

let path1 = transformer(path1);
let path2 = transformer(path2);

let mut all_infos = NameExchange::new();

// 用于校验文件夹路径最后是否为斜杠与双引号的闭包
let dir_check = |s: String| {
let s = PathBuf::from(s);
let mut s = s;
if s.ends_with("\"") {
let s = s.to_str().unwrap().strip_suffix("\"").unwrap();
let s = if s.ends_with("\\") {
s.strip_suffix("\\").unwrap()
} else {
s
};
PathBuf::from(s)
} else {
s
}
s = s.strip_suffix("\"").unwrap().to_string()
};
if s.ends_with("\\") {
s = s.strip_suffix("\\").unwrap().to_string()
};
PathBuf::from(s)
};
let mut packed_path = GetPathInfo {
path1: dir_check(path1),
path2: dir_check(path2),
};

(all_infos.f1.is_exist, all_infos.f2.is_exist) = (packed_path).if_no_exist(exe_dir);
if all_infos.f1.is_exist || all_infos.f2.is_exist {
return 1;
(all_infos.f1.is_exist, all_infos.f2.is_exist) = (packed_path).if_exist(exe_dir);
if (!all_infos.f1.is_exist) || (!all_infos.f2.is_exist) {
return 1_i32;
}
if packed_path.path1 == packed_path.path2 {
return 2_i32;
}
all_infos.f1.exchange.original_path = packed_path.path1.clone();
all_infos.f2.exchange.original_path = packed_path.path2.clone();
Expand All @@ -67,16 +73,23 @@ pub unsafe extern "C" fn exchange(path1: *const c_char, path2: *const c_char) ->
&all_infos.f1.packed_info.name,
&all_infos.f2.packed_info.ext,
);

let mut packed_path_new = GetPathInfo {
//其实没必要mut
path1: all_infos.f1.exchange.new_path.clone(),
path2: all_infos.f2.exchange.new_path.clone(),
};

//println!("{:?} {:?}", &packed_path_new.path1, &packed_path_new.path2); //test
let (exist_new_1, exist_new_2) = GetPathInfo::if_no_exist(&mut packed_path_new, exe_dir);
if (!exist_new_1) || (!exist_new_2) {
return 4;
let (exist_new_1, exist_new_2) = GetPathInfo::if_exist(&mut packed_path_new, exe_dir);
let same_dir = GetPathInfo::if_same_dir(&packed_path_new);
if !same_dir && (exist_new_1 || exist_new_2) {
//不能因为rename函数里面有就删了……
/*
println!(
"same:{}\tnew1:{}\tnew2:{}",
same_dir, exist_new_1, exist_new_2
);
*/
return 3_i32;
}

//1 -> file1 should be renamed first
Expand Down Expand Up @@ -119,3 +132,37 @@ pub unsafe extern "C" fn exchange(path1: *const c_char, path2: *const c_char) ->
}
}
}

#[cfg(test)]
mod tests {
use std::env::args;
use std::{ffi::CString, fs::remove_file};

fn clear_olds() {
let _ = remove_file("file1.ext1");
let _ = remove_file("file2.ext2");
let _ = remove_file("file2.ext1");
let _ = remove_file("file1.ext2");

let mut new_file1 = std::fs::File::create("file1.ext1").unwrap();
let mut new_file2 = std::fs::File::create("file2.ext2").unwrap();
let _ = std::io::Write::write_all(&mut new_file1, b"");
let _ = std::io::Write::write_all(&mut new_file2, b"");
}
#[test]
fn it_works() {
clear_olds();
// 0 => Success,1 => No Exist
// 2 => Permission Denied,3 => New File Already Exists

let trans = |s: String| CString::new(s).unwrap();
let _test_path1 = trans(r"file1.ext1".to_owned());
let _test_path2 = trans(r"file1.ext1".to_owned());

let mut a: Vec<CString> = args().map(|f| trans(f)).collect();
a.remove(0);

let run_result = super::exchange(a[1].as_ptr(), a[2].as_ptr());
println!("{}", run_result);
}
}
23 changes: 17 additions & 6 deletions src/path_checkout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,32 @@ pub struct GetPathInfo {
/// 所有路径相关的操作
impl GetPathInfo {
/// 校验路径是否存在;如果是相对路径,尝试转化为绝对路径
pub fn if_no_exist(&mut self, exe_path: &Path) -> (bool, bool) {
if self.path1.exists() && self.path1.is_relative() {
self.path1 = exe_path.join(self.path1.clone());
pub fn if_exist(&mut self, dir: &Path) -> (bool, bool) {
if self.path1.is_relative() {
self.path1 = dir.join(self.path1.clone().file_name().unwrap());
}
if self.path2.exists() && self.path2.is_relative() {
self.path2 = exe_path.join(self.path2.clone());
if self.path2.is_relative() {
self.path2 = dir.join(self.path2.clone().file_name().unwrap());
}
(!&self.path1.exists(), !&self.path2.exists())
/*
println!(
"Path1: {}\tPath2: {}",
self.path1.display(),
self.path2.display()
); //test
*/
(self.path1.exists(), self.path2.exists())
}

///输入的文件类型是否为文件夹
pub fn if_file(&self) -> (bool, bool) {
(self.path1.is_file(), self.path2.is_file())
}

pub fn if_same_dir(&self) -> bool {
self.path1.parent().unwrap() == self.path2.parent().unwrap()
}

///检测是否存在包含关系(父子目录问题)
pub fn if_root(&self) -> u8 {
//下面必须统一取小写或大写,因为rust的“contains()”大小写敏感
Expand Down

0 comments on commit 1e240f8

Please sign in to comment.