#[allow(warnings)]
pub mod fs {
use std::ffi::OsStr;
use std::fs::{self, File, Metadata, OpenOptions};
use std::io::{self, Read, Seek, Write};
use std::path::{Path, PathBuf};
pub fn append_data_to_file<T: AsRef<[u8]>, P: AsRef<Path>>(path: P, data: T) -> io::Result<()> {
let mut file = OpenOptions::new().create(true).append(true).open(path)?;
file.write_all(data.as_ref())?;
Ok(())
}
pub fn walk_dir_get_files(path: impl ToString) -> io::Result<Vec<PathBuf>> {
let path = path.to_string();
let mut files = walk_dir(path)?;
Ok(files.into_iter().filter(|s| s.is_file()).collect())
}
pub fn walk_dir_get_folders(path: impl ToString) -> io::Result<Vec<PathBuf>> {
let path = path.to_string();
let mut files = walk_dir(path)?;
Ok(files.into_iter().filter(|s| s.is_dir()).collect())
}
pub fn walk_dir(path: impl ToString) -> io::Result<Vec<PathBuf>> {
let path = path.to_string();
let dir = Path::new(&path);
let mut files = Vec::new();
for entry in fs::read_dir(dir)? {
let entry = entry?;
let newpath = entry.path();
if newpath.is_dir() {
files.extend(walk_dir(&newpath.display())?);
files.push(newpath);
} else {
files.push(newpath);
}
}
Ok(files)
}
pub fn move_file(from: &Path, to: &Path) -> io::Result<()> {
fs::rename(from, to)?;
Ok(())
}
pub fn copy_file(from: &Path, to: &Path) -> io::Result<()> {
fs::copy(from, to)?;
Ok(())
}
pub fn move_folder(from: &Path, to: &Path) -> io::Result<()> {
fs::create_dir_all(to)?;
let entries = fs::read_dir(from)?;
for entry in entries {
let entry = entry?;
let source_path = entry.path();
let file_name = entry.file_name();
let target_path = to.join(file_name);
fs::rename(source_path, target_path)?;
}
std::fs::remove_dir_all(from)?;
Ok(())
}
pub fn copy_folder(from: &Path, to: &Path) -> io::Result<()> {
fs::create_dir_all(to)?;
for entry in fs::read_dir(from)? {
let entry = entry?;
let entry_path = entry.path();
let dest_path = to.join(entry.file_name());
if entry_path.is_file() {
fs::copy(&entry_path, &dest_path)?;
} else if entry_path.is_dir() {
copy_folder(&entry_path, &dest_path)?;
}
}
Ok(())
}
pub fn home_dir() -> Option<PathBuf> {
if let Some(home_dir) = std::env::var("HOME").ok().map(PathBuf::from) {
Some(home_dir)
} else {
None
}
}
pub fn metadata<P: AsRef<Path>>(path: P) -> Result<Metadata, String> {
let path = path.as_ref();
std::fs::metadata(path).map_err(|r| format!("failed to get metadata for"))
}
pub fn write_if_changed<P: AsRef<Path>, C: AsRef<[u8]>>(
path: P,
contents: C,
) -> Result<(), String> {
let contents = contents.as_ref();
let mut f = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)
.unwrap();
let mut orig = Vec::new();
f.read_to_end(&mut orig).unwrap();
if orig != contents {
f.set_len(0).unwrap();
f.seek(io::SeekFrom::Start(0)).unwrap();
f.write_all(contents).unwrap();
}
Ok(())
}
pub fn path_to_bytes(path: &Path) -> Result<&[u8], String> {
#[cfg(unix)]
{
use std::os::unix::prelude::*;
Ok(path.as_os_str().as_bytes())
}
#[cfg(windows)]
{
match path.as_os_str().to_str() {
Some(s) => Ok(s.as_bytes()),
None => Err(format!("invalid non-unicode path: {}", path.display())),
}
}
}
pub fn bytes_to_path(bytes: &[u8]) -> Result<PathBuf, String> {
#[cfg(unix)]
{
use std::os::unix::prelude::*;
Ok(PathBuf::from(OsStr::from_bytes(bytes)))
}
#[cfg(windows)]
{
use std::str;
match str::from_utf8(bytes) {
Ok(s) => Ok(PathBuf::from(s)),
Err(..) => Err(format!("invalid non-unicode path")),
}
}
}
pub fn set_not_readonly(p: &Path) -> io::Result<bool> {
let mut perms = p.metadata()?.permissions();
if !perms.readonly() {
return Ok(false);
}
perms.set_readonly(false);
fs::set_permissions(p, perms)?;
Ok(true)
}
}
pub use fs::*;