mirror of
https://github.com/veeso/termscp.git
synced 2025-12-07 09:36:00 -08:00
fmt host.rs
This commit is contained in:
113
src/host/mod.rs
113
src/host/mod.rs
@@ -53,21 +53,19 @@ pub enum HostErrorType {
|
|||||||
|
|
||||||
pub struct HostError {
|
pub struct HostError {
|
||||||
pub error: HostErrorType,
|
pub error: HostErrorType,
|
||||||
pub ioerr: Option<std::io::Error>
|
pub ioerr: Option<std::io::Error>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HostError {
|
impl HostError {
|
||||||
|
|
||||||
/// ### new
|
/// ### new
|
||||||
///
|
///
|
||||||
/// Instantiates a new HostError
|
/// Instantiates a new HostError
|
||||||
pub(crate) fn new(error: HostErrorType, errno: Option<std::io::Error>) -> HostError {
|
pub(crate) fn new(error: HostErrorType, errno: Option<std::io::Error>) -> HostError {
|
||||||
HostError {
|
HostError {
|
||||||
error: error,
|
error: error,
|
||||||
ioerr: errno
|
ioerr: errno,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for HostError {
|
impl std::fmt::Display for HostError {
|
||||||
@@ -83,7 +81,7 @@ impl std::fmt::Display for HostError {
|
|||||||
};
|
};
|
||||||
match &self.ioerr {
|
match &self.ioerr {
|
||||||
Some(err) => write!(f, "{}: {}", code_str, err),
|
Some(err) => write!(f, "{}: {}", code_str, err),
|
||||||
None => write!(f, "{}", code_str)
|
None => write!(f, "{}", code_str),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,7 +178,7 @@ impl Localhost {
|
|||||||
if dir_path.exists() {
|
if dir_path.exists() {
|
||||||
match ignex {
|
match ignex {
|
||||||
true => return Ok(()),
|
true => return Ok(()),
|
||||||
false => return Err(HostError::new(HostErrorType::FileAlreadyExists, None))
|
false => return Err(HostError::new(HostErrorType::FileAlreadyExists, None)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match std::fs::create_dir(dir_path) {
|
match std::fs::create_dir(dir_path) {
|
||||||
@@ -189,12 +187,12 @@ impl Localhost {
|
|||||||
if dir_name.is_relative() {
|
if dir_name.is_relative() {
|
||||||
self.files = match self.scan_dir(self.wrkdir.as_path()) {
|
self.files = match self.scan_dir(self.wrkdir.as_path()) {
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(err) => return Err(err)
|
Err(err) => return Err(err),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
}
|
||||||
Err(err) => Err(HostError::new(HostErrorType::CouldNotCreateFile, Some(err)))
|
Err(err) => Err(HostError::new(HostErrorType::CouldNotCreateFile, Some(err))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +204,7 @@ impl Localhost {
|
|||||||
FsEntry::Directory(dir) => {
|
FsEntry::Directory(dir) => {
|
||||||
// If file doesn't exist; return error
|
// If file doesn't exist; return error
|
||||||
if !dir.abs_path.as_path().exists() {
|
if !dir.abs_path.as_path().exists() {
|
||||||
return Err(HostError::new(HostErrorType::NoSuchFileOrDirectory, None))
|
return Err(HostError::new(HostErrorType::NoSuchFileOrDirectory, None));
|
||||||
}
|
}
|
||||||
// Remove
|
// Remove
|
||||||
match std::fs::remove_dir_all(dir.abs_path.as_path()) {
|
match std::fs::remove_dir_all(dir.abs_path.as_path()) {
|
||||||
@@ -214,17 +212,17 @@ impl Localhost {
|
|||||||
// Update dir
|
// Update dir
|
||||||
self.files = match self.scan_dir(self.wrkdir.as_path()) {
|
self.files = match self.scan_dir(self.wrkdir.as_path()) {
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(err) => return Err(err)
|
Err(err) => return Err(err),
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
|
||||||
Err(err) => Err(HostError::new(HostErrorType::DeleteFailed, Some(err)))
|
|
||||||
}
|
}
|
||||||
},
|
Err(err) => Err(HostError::new(HostErrorType::DeleteFailed, Some(err))),
|
||||||
|
}
|
||||||
|
}
|
||||||
FsEntry::File(file) => {
|
FsEntry::File(file) => {
|
||||||
// If file doesn't exist; return error
|
// If file doesn't exist; return error
|
||||||
if !file.abs_path.as_path().exists() {
|
if !file.abs_path.as_path().exists() {
|
||||||
return Err(HostError::new(HostErrorType::NoSuchFileOrDirectory, None))
|
return Err(HostError::new(HostErrorType::NoSuchFileOrDirectory, None));
|
||||||
}
|
}
|
||||||
// Remove
|
// Remove
|
||||||
match std::fs::remove_file(file.abs_path.as_path()) {
|
match std::fs::remove_file(file.abs_path.as_path()) {
|
||||||
@@ -232,11 +230,11 @@ impl Localhost {
|
|||||||
// Update dir
|
// Update dir
|
||||||
self.files = match self.scan_dir(self.wrkdir.as_path()) {
|
self.files = match self.scan_dir(self.wrkdir.as_path()) {
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(err) => return Err(err)
|
Err(err) => return Err(err),
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
}
|
||||||
Err(err) => Err(HostError::new(HostErrorType::DeleteFailed, Some(err)))
|
Err(err) => Err(HostError::new(HostErrorType::DeleteFailed, Some(err))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -248,18 +246,18 @@ impl Localhost {
|
|||||||
pub fn rename(&mut self, entry: &FsEntry, dst_path: &Path) -> Result<(), HostError> {
|
pub fn rename(&mut self, entry: &FsEntry, dst_path: &Path) -> Result<(), HostError> {
|
||||||
let abs_path: PathBuf = match entry {
|
let abs_path: PathBuf = match entry {
|
||||||
FsEntry::Directory(dir) => dir.abs_path.clone(),
|
FsEntry::Directory(dir) => dir.abs_path.clone(),
|
||||||
FsEntry::File(f) => f.abs_path.clone()
|
FsEntry::File(f) => f.abs_path.clone(),
|
||||||
};
|
};
|
||||||
match std::fs::rename(abs_path.as_path(), dst_path) {
|
match std::fs::rename(abs_path.as_path(), dst_path) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
// Scan dir
|
// Scan dir
|
||||||
self.files = match self.scan_dir(self.wrkdir.as_path()) {
|
self.files = match self.scan_dir(self.wrkdir.as_path()) {
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(err) => return Err(err)
|
Err(err) => return Err(err),
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
}
|
||||||
Err(err) => Err(HostError::new(HostErrorType::CouldNotCreateFile, Some(err)))
|
Err(err) => Err(HostError::new(HostErrorType::CouldNotCreateFile, Some(err))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +268,7 @@ impl Localhost {
|
|||||||
pub fn stat(&self, path: &Path) -> Result<FsEntry, HostError> {
|
pub fn stat(&self, path: &Path) -> Result<FsEntry, HostError> {
|
||||||
let attr: Metadata = match fs::metadata(path.clone()) {
|
let attr: Metadata = match fs::metadata(path.clone()) {
|
||||||
Ok(metadata) => metadata,
|
Ok(metadata) => metadata,
|
||||||
Err(err) => return Err(HostError::new(HostErrorType::FileNotAccessible, Some(err)))
|
Err(err) => return Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
||||||
};
|
};
|
||||||
let file_name: String = String::from(path.file_name().unwrap().to_str().unwrap_or(""));
|
let file_name: String = String::from(path.file_name().unwrap().to_str().unwrap_or(""));
|
||||||
// Match dir / file
|
// Match dir / file
|
||||||
@@ -325,7 +323,7 @@ impl Localhost {
|
|||||||
pub fn stat(&self, path: &Path) -> Result<FsEntry, HostError> {
|
pub fn stat(&self, path: &Path) -> Result<FsEntry, HostError> {
|
||||||
let attr: Metadata = match fs::metadata(path.clone()) {
|
let attr: Metadata = match fs::metadata(path.clone()) {
|
||||||
Ok(metadata) => metadata,
|
Ok(metadata) => metadata,
|
||||||
Err(err) => return Err(HostError::new(HostErrorType::FileNotAccessible, Some(err)))
|
Err(err) => return Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
||||||
};
|
};
|
||||||
let file_name: String = String::from(path.file_name().unwrap().to_str().unwrap_or(""));
|
let file_name: String = String::from(path.file_name().unwrap().to_str().unwrap_or(""));
|
||||||
// Match dir / file
|
// Match dir / file
|
||||||
@@ -377,9 +375,14 @@ impl Localhost {
|
|||||||
/// Open file for read
|
/// Open file for read
|
||||||
pub fn open_file_read(&self, file: &Path) -> Result<File, HostError> {
|
pub fn open_file_read(&self, file: &Path) -> Result<File, HostError> {
|
||||||
if !self.file_exists(file) {
|
if !self.file_exists(file) {
|
||||||
return Err(HostError::new(HostErrorType::NoSuchFileOrDirectory, None))
|
return Err(HostError::new(HostErrorType::NoSuchFileOrDirectory, None));
|
||||||
}
|
}
|
||||||
match OpenOptions::new().create(false).read(true).write(false).open(file) {
|
match OpenOptions::new()
|
||||||
|
.create(false)
|
||||||
|
.read(true)
|
||||||
|
.write(false)
|
||||||
|
.open(file)
|
||||||
|
{
|
||||||
Ok(f) => Ok(f),
|
Ok(f) => Ok(f),
|
||||||
Err(err) => Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
Err(err) => Err(HostError::new(HostErrorType::FileNotAccessible, Some(err))),
|
||||||
}
|
}
|
||||||
@@ -389,7 +392,12 @@ impl Localhost {
|
|||||||
///
|
///
|
||||||
/// Open file for write
|
/// Open file for write
|
||||||
pub fn open_file_write(&self, file: &Path) -> Result<File, HostError> {
|
pub fn open_file_write(&self, file: &Path) -> Result<File, HostError> {
|
||||||
match OpenOptions::new().create(true).write(true).truncate(true).open(file) {
|
match OpenOptions::new()
|
||||||
|
.create(true)
|
||||||
|
.write(true)
|
||||||
|
.truncate(true)
|
||||||
|
.open(file)
|
||||||
|
{
|
||||||
Ok(f) => Ok(f),
|
Ok(f) => Ok(f),
|
||||||
Err(err) => match self.file_exists(file) {
|
Err(err) => match self.file_exists(file) {
|
||||||
true => Err(HostError::new(HostErrorType::ReadonlyFile, Some(err))),
|
true => Err(HostError::new(HostErrorType::ReadonlyFile, Some(err))),
|
||||||
@@ -442,12 +450,12 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
#[cfg(any(unix, macos, linux))]
|
#[cfg(any(unix, macos, linux))]
|
||||||
use std::io::Write;
|
|
||||||
#[cfg(any(unix, macos, linux))]
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
#[cfg(any(unix, macos, linux))]
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
#[cfg(any(unix, macos, linux))]
|
#[cfg(any(unix, macos, linux))]
|
||||||
use std::os::unix::fs::{PermissionsExt, symlink};
|
use std::os::unix::fs::{symlink, PermissionsExt};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_host_error_new() {
|
fn test_host_error_new() {
|
||||||
@@ -586,7 +594,6 @@ mod tests {
|
|||||||
//fs::set_permissions(file.path(), perms)?;
|
//fs::set_permissions(file.path(), perms)?;
|
||||||
assert!(host.open_file_write(file.path()).is_err());
|
assert!(host.open_file_write(file.path()).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(unix, macos, linux))]
|
#[cfg(any(unix, macos, linux))]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_host_localhost_symlinks() {
|
fn test_host_localhost_symlinks() {
|
||||||
@@ -594,7 +601,11 @@ mod tests {
|
|||||||
// Create sample file
|
// Create sample file
|
||||||
assert!(File::create(format!("{}/foo.txt", tmpdir.path().display()).as_str()).is_ok());
|
assert!(File::create(format!("{}/foo.txt", tmpdir.path().display()).as_str()).is_ok());
|
||||||
// Create symlink
|
// Create symlink
|
||||||
assert!(symlink(format!("{}/foo.txt", tmpdir.path().display()), format!("{}/bar.txt", tmpdir.path().display())).is_ok());
|
assert!(symlink(
|
||||||
|
format!("{}/foo.txt", tmpdir.path().display()),
|
||||||
|
format!("{}/bar.txt", tmpdir.path().display())
|
||||||
|
)
|
||||||
|
.is_ok());
|
||||||
// Get dir
|
// Get dir
|
||||||
let host: Localhost = Localhost::new(PathBuf::from(tmpdir.path())).ok().unwrap();
|
let host: Localhost = Localhost::new(PathBuf::from(tmpdir.path())).ok().unwrap();
|
||||||
let files: Vec<FsEntry> = host.list_dir();
|
let files: Vec<FsEntry> = host.list_dir();
|
||||||
@@ -606,22 +617,28 @@ mod tests {
|
|||||||
if file_0.name == String::from("foo.txt") {
|
if file_0.name == String::from("foo.txt") {
|
||||||
assert!(file_0.symlink.is_none());
|
assert!(file_0.symlink.is_none());
|
||||||
} else {
|
} else {
|
||||||
assert_eq!(*file_0.symlink.as_ref().unwrap(), PathBuf::from(format!("{}/foo.txt", tmpdir.path().display())));
|
assert_eq!(
|
||||||
|
*file_0.symlink.as_ref().unwrap(),
|
||||||
|
PathBuf::from(format!("{}/foo.txt", tmpdir.path().display()))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => panic!("expected entry 0 to be file: {:?}", file_0)
|
_ => panic!("expected entry 0 to be file: {:?}", file_0),
|
||||||
};
|
};
|
||||||
// Verify simlink
|
// Verify simlink
|
||||||
let file_1: &FsEntry = files.get(1).unwrap();
|
let file_1: &FsEntry = files.get(1).unwrap();
|
||||||
match file_1 {
|
match file_1 {
|
||||||
FsEntry::File(file_1) => {
|
FsEntry::File(file_1) => {
|
||||||
if file_1.name == String::from("bar.txt") {
|
if file_1.name == String::from("bar.txt") {
|
||||||
assert_eq!(*file_1.symlink.as_ref().unwrap(), PathBuf::from(format!("{}/foo.txt", tmpdir.path().display())));
|
assert_eq!(
|
||||||
|
*file_1.symlink.as_ref().unwrap(),
|
||||||
|
PathBuf::from(format!("{}/foo.txt", tmpdir.path().display()))
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
assert!(file_1.symlink.is_none());
|
assert!(file_1.symlink.is_none());
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
_ => panic!("expected entry 0 to be file: {:?}", file_1)
|
_ => panic!("expected entry 0 to be file: {:?}", file_1),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,7 +655,9 @@ mod tests {
|
|||||||
// Try to re-create directory
|
// Try to re-create directory
|
||||||
assert!(host.mkdir(PathBuf::from("test_dir").as_path()).is_err());
|
assert!(host.mkdir(PathBuf::from("test_dir").as_path()).is_err());
|
||||||
// Try abs path
|
// Try abs path
|
||||||
assert!(host.mkdir_ex(PathBuf::from("/tmp/test_dir_123456789").as_path(), true).is_ok());
|
assert!(host
|
||||||
|
.mkdir_ex(PathBuf::from("/tmp/test_dir_123456789").as_path(), true)
|
||||||
|
.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -668,22 +687,28 @@ mod tests {
|
|||||||
fn test_host_localhost_rename() {
|
fn test_host_localhost_rename() {
|
||||||
let tmpdir: tempfile::TempDir = tempfile::TempDir::new().unwrap();
|
let tmpdir: tempfile::TempDir = tempfile::TempDir::new().unwrap();
|
||||||
// Create sample file
|
// Create sample file
|
||||||
let src_path: PathBuf = PathBuf::from(format!("{}/foo.txt", tmpdir.path().display()).as_str());
|
let src_path: PathBuf =
|
||||||
|
PathBuf::from(format!("{}/foo.txt", tmpdir.path().display()).as_str());
|
||||||
assert!(File::create(src_path.as_path()).is_ok());
|
assert!(File::create(src_path.as_path()).is_ok());
|
||||||
let mut host: Localhost = Localhost::new(PathBuf::from(tmpdir.path())).ok().unwrap();
|
let mut host: Localhost = Localhost::new(PathBuf::from(tmpdir.path())).ok().unwrap();
|
||||||
let files: Vec<FsEntry> = host.list_dir();
|
let files: Vec<FsEntry> = host.list_dir();
|
||||||
assert_eq!(files.len(), 1); // There should be 1 file now
|
assert_eq!(files.len(), 1); // There should be 1 file now
|
||||||
assert_eq!(get_filename(files.get(0).unwrap()), String::from("foo.txt"));
|
assert_eq!(get_filename(files.get(0).unwrap()), String::from("foo.txt"));
|
||||||
// Rename file
|
// Rename file
|
||||||
let dst_path: PathBuf = PathBuf::from(format!("{}/bar.txt", tmpdir.path().display()).as_str());
|
let dst_path: PathBuf =
|
||||||
assert!(host.rename(files.get(0).unwrap(), dst_path.as_path()).is_ok());
|
PathBuf::from(format!("{}/bar.txt", tmpdir.path().display()).as_str());
|
||||||
|
assert!(host
|
||||||
|
.rename(files.get(0).unwrap(), dst_path.as_path())
|
||||||
|
.is_ok());
|
||||||
// There should be still 1 file now, but named bar.txt
|
// There should be still 1 file now, but named bar.txt
|
||||||
let files: Vec<FsEntry> = host.list_dir();
|
let files: Vec<FsEntry> = host.list_dir();
|
||||||
assert_eq!(files.len(), 1); // There should be 0 files now
|
assert_eq!(files.len(), 1); // There should be 0 files now
|
||||||
assert_eq!(get_filename(files.get(0).unwrap()), String::from("bar.txt"));
|
assert_eq!(get_filename(files.get(0).unwrap()), String::from("bar.txt"));
|
||||||
// Fail
|
// Fail
|
||||||
let bad_path: PathBuf = PathBuf::from("/asdailsjoidoewojdijow/ashdiuahu");
|
let bad_path: PathBuf = PathBuf::from("/asdailsjoidoewojdijow/ashdiuahu");
|
||||||
assert!(host.rename(files.get(0).unwrap(), bad_path.as_path()).is_err());
|
assert!(host
|
||||||
|
.rename(files.get(0).unwrap(), bad_path.as_path())
|
||||||
|
.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ### create_sample_file
|
/// ### create_sample_file
|
||||||
@@ -705,7 +730,7 @@ mod tests {
|
|||||||
fn get_filename(entry: &FsEntry) -> String {
|
fn get_filename(entry: &FsEntry) -> String {
|
||||||
match entry {
|
match entry {
|
||||||
FsEntry::Directory(d) => d.name.clone(),
|
FsEntry::Directory(d) => d.name.clone(),
|
||||||
FsEntry::File(f) => f.name.clone()
|
FsEntry::File(f) => f.name.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user