use std::fs;
use std::io::{self, Write};
use std::path::{Path, PathBuf};
pub fn read_string<P: AsRef<Path>>(path: P) -> io::Result<String> {
fs::read_to_string(path)
}
pub fn read_data<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
fs::read(path)
}
pub fn write_string<P: AsRef<Path>>(path: P, content: &str) -> io::Result<()> {
if let Some(parent) = Path::new(path.as_ref()).parent() {
fs::create_dir_all(parent)?;
}
fs::write(path, content)
}
pub fn write_data<P: AsRef<Path>>(path: P, data: &[u8]) -> io::Result<()> {
if let Some(parent) = Path::new(path.as_ref()).parent() {
fs::create_dir_all(parent)?;
}
let mut file = fs::File::create(path)?;
file.write_all(data)
}
pub fn copy_file<P: AsRef<Path>>(from: P, to: P) -> io::Result<u64> {
if let Some(parent) = Path::new(to.as_ref()).parent() {
fs::create_dir_all(parent)?;
}
fs::copy(from, to)
}
pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
fs::remove_file(path)
}
pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
fs::create_dir_all(path)
}
pub fn exists<P: AsRef<Path>>(path: P) -> bool {
Path::new(path.as_ref()).exists()
}
pub fn file_size<P: AsRef<Path>>(path: P) -> io::Result<u64> {
Ok(fs::metadata(path)?.len())
}
pub fn list_files<P: AsRef<Path>>(dir: P) -> io::Result<Vec<PathBuf>> {
let mut files = vec![];
for entry in fs::read_dir(dir)? {
let entry = entry?;
if entry.path().is_file() {
files.push(entry.path());
}
}
Ok(files)
}
pub fn list_files_recursive<P: AsRef<Path>>(dir: P) -> io::Result<Vec<PathBuf>> {
let mut files = vec![];
visit_dirs(dir.as_ref(), &mut files)?;
Ok(files)
}
fn visit_dirs(dir: &Path, files: &mut Vec<PathBuf>) -> io::Result<()> {
if dir.is_dir() {
for entry in fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
visit_dirs(&path, files)?;
} else {
files.push(path);
}
}
}
Ok(())
}
pub fn file_name<P: AsRef<Path>>(path: P) -> Option<String> {
Path::new(path.as_ref())
.file_name()
.and_then(|os_str| os_str.to_str())
.map(|s| s.to_string())
}
pub fn parent_dir<P: AsRef<Path>>(path: P) -> Option<PathBuf> {
Path::new(path.as_ref()).parent().map(|p| p.to_path_buf())
}
pub fn create_parent_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
if let Some(parent) = Path::new(path.as_ref()).parent() {
fs::create_dir_all(parent)?;
}
Ok(())
}
pub fn extension<P: AsRef<Path>>(path: P) -> Option<String> {
Path::new(path.as_ref())
.extension()
.and_then(|os_str| os_str.to_str())
.map(|s| s.to_string())
}
pub fn join_paths<P: AsRef<Path>>(segments: &[P]) -> PathBuf {
let mut iter = segments.iter();
let mut path = if let Some(first) = iter.next() {
PathBuf::from(first.as_ref())
} else {
PathBuf::new()
};
for seg in iter {
path.push(seg.as_ref());
}
path
}
pub fn absolute_path<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
std::path::absolute(path)
}