use crate::error::Error;
use std::fs;
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
pub struct FS;
impl FS {
pub fn new() -> Self {
Self {}
}
pub fn create_dir(&self, path: &str) -> Result<(), Error> {
if !Path::new(path).exists() {
return fs::create_dir_all(path)
.map_err(|e| Error::FS(format!("Cannot create directory '{path}' ({e})")));
}
Result::Ok(())
}
pub fn copy_dir(&self, from: &str, to: &str) -> Result<(), Error> {
Command::new("cp")
.arg("--recursive")
.arg(from)
.arg(to)
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
.map_err(Error::Io)?
.wait()
.map(|_| ())
.map_err(|e| {
Error::FS(format!(
"Cannot copy directory from '{from}' to '{to}' ({e})"
))
})
}
pub fn read_dir(&self, path: &str) -> Result<fs::ReadDir, Error> {
fs::read_dir(path).map_err(|e| Error::FS(format!("Cannot read directory '{path}' ({e})")))
}
pub fn read_dir_file_paths(&self, path: &str) -> Result<Vec<PathBuf>, Error> {
self.read_dir(path)
.map(|dir| dir.flatten().map(|dir| dir.path()).collect())
}
pub fn remove_dir(&self, path: &str) -> Result<(), Error> {
fs::remove_dir_all(path)
.map_err(|e| Error::FS(format!("Cannot remove directory '{path}' ({e})")))
}
pub fn setup_directory_access(&self, path: &str) -> Result<(), Error> {
self.create_dir(path)?;
let permission = fs::metadata(path)
.map_err(|e| Error::FS(format!("Cannot read directory metadata '{path}' ({e})")))?
.permissions();
if permission.readonly() {
return Err(Error::FS(format!("Cannot write directory '{path}'")));
}
Result::Ok(())
}
pub fn create_file(&self, path: &str) -> Result<fs::File, Error> {
std::fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(path)
.map_err(|e| Error::FS(format!("Cannot create file '{path}' ({e})")))
}
pub fn open_file(&self, path: &str) -> Result<fs::File, Error> {
fs::File::open(path).map_err(|e| Error::FS(format!("Cannot open file '{path}' ({e})")))
}
pub fn path_exists(&self, path: &str) -> bool {
Path::new(path).exists()
}
pub fn write_file(&self, path: &str, data: &[u8]) -> Result<(), Error> {
self.create_file(path)?
.write_all(data)
.map_err(|e| Error::FS(format!("Cannot write file '{path}' ({e})")))
}
pub fn read_file_to_string(&self, path: &str) -> Result<String, Error> {
fs::read_to_string(path).map_err(|e| Error::FS(format!("Cannot read file '{path}' ({e})")))
}
pub fn rename_file(&self, from: &str, to: &str) -> Result<(), Error> {
fs::rename(from, to)
.map_err(|e| Error::FS(format!("Cannot rename file from '{from}' to '{to}' ({e})")))
}
pub fn remove_file(&self, path: &str) -> Result<(), Error> {
fs::remove_file(path).map_err(|e| Error::FS(format!("Cannot delete file '{path}' ({e})")))
}
}