fmt host.rs

This commit is contained in:
ChristianVisintin
2020-12-01 11:09:55 +01:00
parent 02ca8c6046
commit 1364fd34ed

View File

@@ -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(),
} }
} }
} }