use rand::{distributions::Alphanumeric, Rng};
use std::env::temp_dir;
use std::fs::{self, File, OpenOptions};
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use tempfile::TempDir;
pub fn read_file_to_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
fs::read_to_string(path)
}
pub fn read_file_to_bytes<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
fs::read(path)
}
pub fn write_string_to_file<P: AsRef<Path>>(path: P, content: &str) -> io::Result<()> {
fs::write(path, content)
}
pub fn write_bytes_to_file<P: AsRef<Path>>(path: P, data: &[u8]) -> io::Result<()> {
fs::write(path, data)
}
pub fn append_string_to_file<P: AsRef<Path>>(path: P, content: &str) -> io::Result<()> {
let mut file = OpenOptions::new().append(true).create(true).open(path)?;
file.write_all(content.as_bytes())
}
pub fn copy_file<P: AsRef<Path>>(src: P, dst: P) -> io::Result<u64> {
fs::copy(src, dst)
}
pub fn path_exists<P: AsRef<Path>>(path: P) -> bool {
path.as_ref().exists()
}
pub fn is_file<P: AsRef<Path>>(path: P) -> bool {
path.as_ref().is_file()
}
pub fn is_dir<P: AsRef<Path>>(path: P) -> bool {
path.as_ref().is_dir()
}
pub fn is_symlink<P: AsRef<Path>>(path: P) -> io::Result<bool> {
let metadata = fs::symlink_metadata(path)?;
Ok(metadata.file_type().is_symlink())
}
#[cfg(unix)]
use std::os::unix::fs::symlink as symlink_unix;
#[cfg(windows)]
use std::os::windows::fs::{
symlink_dir as symlink_dir_windows, symlink_file as symlink_file_windows,
};
pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) -> io::Result<()> {
let original = original.as_ref();
let link = link.as_ref();
if original.is_dir() {
#[cfg(unix)]
{
symlink_unix(original, link)
}
#[cfg(windows)]
{
symlink_dir_windows(original, link)
}
} else {
#[cfg(unix)]
{
symlink_unix(original, link)
}
#[cfg(windows)]
{
symlink_file_windows(original, link)
}
}
}
pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
fs::create_dir_all(path)
}
pub fn remove_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
let path = path.as_ref();
if !path.exists() {
return Ok(());
}
if is_file(path) {
fs::remove_file(path)
} else {
fs::remove_dir_all(path)
}
}
pub fn get_file_size<P: AsRef<Path>>(path: P) -> io::Result<u64> {
let metadata = fs::metadata(path)?;
Ok(metadata.len())
}
pub fn create_temp_file() -> io::Result<(PathBuf, File)> {
let mut rng = rand::thread_rng();
let filename: String = std::iter::repeat(())
.map(|()| rng.sample(Alphanumeric))
.take(12)
.map(char::from)
.collect();
let mut path = temp_dir();
path.push(filename);
let file = OpenOptions::new()
.read(true)
.write(true)
.create_new(true)
.open(&path)?;
Ok((path, file))
}
pub fn create_temp_dir() -> io::Result<TempDir> {
TempDir::new()
}