1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

mv: split exec into smaller functions

This commit is contained in:
Sylvestre Ledru 2023-05-06 12:11:01 +02:00
parent a5a39b6ba8
commit 1b99376d95

View file

@ -238,11 +238,9 @@ fn determine_overwrite_mode(matches: &ArgMatches) -> OverwriteMode {
} }
} }
fn exec(files: &[OsString], b: &Behavior) -> UResult<()> { fn parse_paths(files: &[OsString], b: &Behavior) -> Vec<PathBuf> {
let paths: Vec<PathBuf> = {
let paths = files.iter().map(Path::new); let paths = files.iter().map(Path::new);
// Strip slashes from path, if strip opt present
if b.strip_slashes { if b.strip_slashes {
paths paths
.map(|p| p.components().as_path().to_owned()) .map(|p| p.components().as_path().to_owned())
@ -250,33 +248,18 @@ fn exec(files: &[OsString], b: &Behavior) -> UResult<()> {
} else { } else {
paths.map(|p| p.to_owned()).collect::<Vec<PathBuf>>() paths.map(|p| p.to_owned()).collect::<Vec<PathBuf>>()
} }
};
if let Some(ref name) = b.target_dir {
return move_files_into_dir(&paths, &PathBuf::from(name), b);
} }
match paths.len() {
/* case 0/1 are not possible thanks to clap */ fn handle_two_paths(source: &Path, target: &Path, b: &Behavior) -> UResult<()> {
2 => {
let source = &paths[0];
let target = &paths[1];
// Here we use the `symlink_metadata()` method instead of `exists()`,
// since it handles dangling symlinks correctly. The method gives an
// `Ok()` results unless the source does not exist, or the user
// lacks permission to access metadata.
if source.symlink_metadata().is_err() { if source.symlink_metadata().is_err() {
return Err(MvError::NoSuchFile(source.quote().to_string()).into()); return Err(MvError::NoSuchFile(source.quote().to_string()).into());
} }
// GNU semantics are: if the source and target are the same, no move occurs and we print an error
if source.eq(target) || are_hardlinks_to_same_file(source, target) { if source.eq(target) || are_hardlinks_to_same_file(source, target) {
// Done to match GNU semantics for the dot file
if source.eq(Path::new(".")) || source.ends_with("/.") || source.is_file() { if source.eq(Path::new(".")) || source.ends_with("/.") || source.is_file() {
return Err(MvError::SameFile( return Err(
source.quote().to_string(), MvError::SameFile(source.quote().to_string(), target.quote().to_string()).into(),
target.quote().to_string(), );
)
.into());
} else { } else {
return Err(MvError::SelfSubdirectory(source.display().to_string()).into()); return Err(MvError::SelfSubdirectory(source.display().to_string()).into());
} }
@ -292,7 +275,7 @@ fn exec(files: &[OsString], b: &Behavior) -> UResult<()> {
Err(MvError::DirectoryToNonDirectory(target.quote().to_string()).into()) Err(MvError::DirectoryToNonDirectory(target.quote().to_string()).into())
} }
} else { } else {
move_files_into_dir(&[source.clone()], target, b) move_files_into_dir(&[source.to_path_buf()], target, b)
} }
} else if target.exists() && source.is_dir() { } else if target.exists() && source.is_dir() {
match b.overwrite { match b.overwrite {
@ -313,11 +296,12 @@ fn exec(files: &[OsString], b: &Behavior) -> UResult<()> {
rename(source, target, b, None).map_err(|e| USimpleError::new(1, format!("{e}"))) rename(source, target, b, None).map_err(|e| USimpleError::new(1, format!("{e}")))
} }
} }
_ => {
fn handle_multiple_paths(paths: &[PathBuf], b: &Behavior) -> UResult<()> {
if b.no_target_dir { if b.no_target_dir {
return Err(UUsageError::new( return Err(UUsageError::new(
1, 1,
format!("mv: extra operand {}", files[2].quote()), format!("mv: extra operand {}", paths[2].quote()),
)); ));
} }
let target_dir = paths.last().unwrap(); let target_dir = paths.last().unwrap();
@ -325,6 +309,17 @@ fn exec(files: &[OsString], b: &Behavior) -> UResult<()> {
move_files_into_dir(sources, target_dir, b) move_files_into_dir(sources, target_dir, b)
} }
fn exec(files: &[OsString], b: &Behavior) -> UResult<()> {
let paths = parse_paths(files, b);
if let Some(ref name) = b.target_dir {
return move_files_into_dir(&paths, &PathBuf::from(name), b);
}
match paths.len() {
2 => handle_two_paths(&paths[0], &paths[1], b),
_ => handle_multiple_paths(&paths, b),
} }
} }