Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions src/dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,7 @@ where
overwrite: options.overwrite,
skip_exist: options.skip_exist,
buffer_size: options.buffer_size,
follow: false,
};
let mut result_copy: Result<u64>;
let mut work = true;
Expand Down Expand Up @@ -726,7 +727,8 @@ where
}
let item = item.unwrap().to_string();

if path.as_ref().is_dir() {
let meta = path.as_ref().symlink_metadata()?;
if meta.is_dir() {
dir_size = path.as_ref().metadata()?.len();
directories.push(item);
if depth == 0 || depth > 1 {
Expand All @@ -749,7 +751,7 @@ where
}
}
} else {
dir_size = path.as_ref().metadata()?.len();
dir_size = meta.len();
files.push(item);
}
Ok(DirContent {
Expand Down Expand Up @@ -931,6 +933,7 @@ where
overwrite: options.overwrite,
skip_exist: options.skip_exist,
buffer_size: options.buffer_size,
follow: false,
};

if let Some(file_name) = file_name.to_str() {
Expand All @@ -940,7 +943,7 @@ where
}

info_process.file_bytes_copied = 0;
info_process.file_total_bytes = Path::new(&file).metadata()?.len();
info_process.file_total_bytes = Path::new(&file).symlink_metadata()?.len();

let mut result_copy: Result<u64>;
let mut work = true;
Expand Down Expand Up @@ -1126,6 +1129,7 @@ where
overwrite: options.overwrite,
skip_exist: options.skip_exist,
buffer_size: options.buffer_size,
follow: false,
};

let mut result_copy: Result<u64>;
Expand All @@ -1146,6 +1150,7 @@ where
}
}
}

if is_remove {
remove(from)?;
}
Expand Down Expand Up @@ -1268,6 +1273,7 @@ where
overwrite: options.overwrite,
skip_exist: options.skip_exist,
buffer_size: options.buffer_size,
follow: false,
};

if let Some(file_name) = file_name.to_str() {
Expand All @@ -1277,7 +1283,7 @@ where
}

info_process.file_bytes_copied = 0;
info_process.file_total_bytes = Path::new(&file).metadata()?.len();
info_process.file_total_bytes = Path::new(&file).symlink_metadata()?.len();

let mut result_copy: Result<u64>;
let mut work = true;
Expand Down
112 changes: 70 additions & 42 deletions src/file.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
use crate::error::{Error, ErrorKind, Result};
use std;
use std::fs::{remove_file, File};
use std::fs::{read_link, remove_file, File};
use std::io::{Read, Write};
#[cfg(any(unix, target_os = "redox"))]
use std::os::unix::fs::symlink;
#[cfg(target_os = "wasi")]
use std::os::wasi::fs::symlink_path as symlink;
#[cfg(windows)]
use std::os::windows::fs::{symlink_dir, symlink_file, FileTypeExt};
use std::path::Path;

// Options and flags which can be used to configure how a file will be copied or moved.
Expand All @@ -12,6 +18,8 @@ pub struct CopyOptions {
pub skip_exist: bool,
/// Sets buffer size for copy/move work only with receipt information about process work.
pub buffer_size: usize,
/// Follows the last symbolic link in the path
pub follow: bool,
}

impl CopyOptions {
Expand All @@ -30,6 +38,7 @@ impl CopyOptions {
overwrite: false,
skip_exist: false,
buffer_size: 64000, //64kb
follow: true,
}
}

Expand Down Expand Up @@ -94,34 +103,43 @@ where
Q: AsRef<Path>,
{
let from = from.as_ref();
if !from.exists() {
if let Some(msg) = from.to_str() {
let msg = format!("Path \"{}\" does not exist or you don't have access!", msg);
err!(&msg, ErrorKind::NotFound);
let to = to.as_ref();

if !options.overwrite && to.symlink_metadata().is_ok() {
if !options.skip_exist {
err!(
&format!("Path \"{}\" exists", to.display()),
ErrorKind::AlreadyExists
);
} else {
return Ok(0);
}
err!(
"Path does not exist or you don't have access!",
ErrorKind::NotFound
);
}

if !from.is_file() {
if let Some(msg) = from.to_str() {
let msg = format!("Path \"{}\" is not a file!", msg);
err!(&msg, ErrorKind::InvalidFile);
if !options.follow && from.is_symlink() {
#[cfg(any(unix, target_os = "wasi", target_os = "redox"))]
symlink(read_link(from)?, to)?;
#[cfg(windows)]
if from.symlink_metadata()?.file_type().is_symlink_dir() {
symlink_dir(read_link(from)?, to)?;
} else {
symlink_file(read_link(from)?, to)?;
}
err!("Path is not a file!", ErrorKind::InvalidFile);
return Ok(to.as_os_str().len() as u64);
}

if !options.overwrite && to.as_ref().exists() {
if options.skip_exist {
return Ok(0);
}
if !from.try_exists()? {
err!(
&format!("Path \"{}\" doesn't exist!", from.display()),
ErrorKind::NotFound
);
}

if let Some(msg) = to.as_ref().to_str() {
let msg = format!("Path \"{}\" exists", msg);
err!(&msg, ErrorKind::AlreadyExists);
}
if !from.is_file() {
err!(
&format!("Path \"{}\" is not a file!", from.display()),
ErrorKind::InvalidFile
);
}

Ok(std::fs::copy(from, to)?)
Expand Down Expand Up @@ -164,35 +182,45 @@ where
F: FnMut(TransitProcess),
{
let from = from.as_ref();
if !from.exists() {
if let Some(msg) = from.to_str() {
let msg = format!("Path \"{}\" does not exist or you don't have access!", msg);
err!(&msg, ErrorKind::NotFound);
let to = to.as_ref();

if !options.overwrite && (to.try_exists()? || to.symlink_metadata().is_ok()) {
if !options.skip_exist {
err!(
&format!("Path \"{}\" exists", to.display()),
ErrorKind::AlreadyExists
);
} else {
return Ok(0);
}
}

if !options.follow && from.is_symlink() {
#[cfg(any(unix, target_os = "wasi", target_os = "redox"))]
symlink(read_link(from)?, to)?;
#[cfg(windows)]
if from.symlink_metadata()?.file_type().is_symlink_dir() {
symlink_dir(read_link(from)?, to)?;
} else {
symlink_file(read_link(from)?, to)?;
}
return Ok(to.as_os_str().len() as u64);
}

if !from.try_exists()? {
err!(
"Path does not exist or you don't have access!",
&format!("Path \"{}\" doesn't exist!", from.display()),
ErrorKind::NotFound
);
}

if !from.is_file() {
if let Some(msg) = from.to_str() {
let msg = format!("Path \"{}\" is not a file!", msg);
err!(&msg, ErrorKind::InvalidFile);
}
err!("Path is not a file!", ErrorKind::InvalidFile);
err!(
&format!("Path \"{}\" is not a file!", from.display()),
ErrorKind::InvalidFile
);
}

if !options.overwrite && to.as_ref().exists() {
if options.skip_exist {
return Ok(0);
}

if let Some(msg) = to.as_ref().to_str() {
let msg = format!("Path \"{}\" exists", msg);
err!(&msg, ErrorKind::AlreadyExists);
}
}
let mut file_from = File::open(from)?;
let mut buf = vec![0; options.buffer_size];
let file_size = file_from.metadata()?.len();
Expand Down
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![cfg_attr(target_os = "wasi", feature(wasi_ext))]

macro_rules! err {
($text:expr, $kind:expr) => {
return Err(Error::new($kind, $text))
Expand Down Expand Up @@ -354,6 +356,7 @@ where
overwrite: options.overwrite,
skip_exist: options.skip_exist,
buffer_size: options.buffer_size,
follow: false,
};

if let Some(file_name) = item.file_name() {
Expand Down Expand Up @@ -541,6 +544,7 @@ where
overwrite: options.overwrite,
skip_exist: options.skip_exist,
buffer_size: options.buffer_size,
follow: false,
};

if let Some(file_name) = item.file_name() {
Expand Down Expand Up @@ -666,6 +670,7 @@ where
overwrite: options.overwrite,
skip_exist: options.skip_exist,
buffer_size: options.buffer_size,
follow: false,
};

if let Some(file_name) = item.file_name() {
Expand Down
Loading