1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
use std::path::{Path, PathBuf}; use crate::{error::fs_err, Result}; pub fn rm_rf(path: impl AsRef<Path>) -> Result<()> { _rm_rf(path.as_ref()) } fn _rm_rf(path: &Path) -> Result<()> { if !path.exists() { return Ok(()); } with_path(path, if path.is_file() { std::fs::remove_file(path) } else { remove_dir_all(path) }) } pub fn read_file(path: impl AsRef<Path>) -> Result<String> { _read_file(path.as_ref()) } fn _read_file(path: &Path) -> Result<String> { with_path(path, std::fs::read_to_string(path)) } pub fn write_file(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> Result<()> { _write_file(path.as_ref(), contents.as_ref()) } fn _write_file(path: &Path, contents: &[u8]) -> Result<()> { with_path(path, std::fs::write(path, contents)) } pub fn mkdir_p(path: impl AsRef<Path>) -> Result<()> { _mkdir_p(path.as_ref()) } fn _mkdir_p(path: &Path) -> Result<()> { with_path(path, std::fs::create_dir_all(path)) } pub fn cp(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> Result<()> { _cp(src.as_ref(), dst.as_ref()) } fn _cp(src: &Path, dst: &Path) -> Result<()> { with_path(src, std::fs::copy(src, dst)).map(|_size| ()) } pub fn read_dir(path: impl AsRef<Path>) -> Result<Vec<PathBuf>> { _read_dir(path.as_ref()) } fn _read_dir(path: &Path) -> Result<Vec<PathBuf>> { with_path(path, read_dir_aux(path)) } pub fn cwd() -> Result<PathBuf> { with_path(&Path::new("."), std::env::current_dir()) } fn with_path<T>(path: &Path, res: Result<T, std::io::Error>) -> Result<T> { res.map_err(|io_err| fs_err(path.to_path_buf(), io_err)) } #[cfg(not(windows))] fn remove_dir_all(path: &Path) -> std::io::Result<()> { std::fs::remove_dir_all(path) } #[cfg(windows)] fn remove_dir_all(path: &Path) -> std::io::Result<()> { for _ in 0..99 { if std::fs::remove_dir_all(path).is_ok() { return Ok(()); } std::thread::sleep(std::time::Duration::from_millis(10)) } std::fs::remove_dir_all(path) } fn read_dir_aux(path: &Path) -> std::io::Result<Vec<PathBuf>> { let mut res = Vec::new(); for entry in std::fs::read_dir(path)? { let entry = entry?; res.push(entry.path()) } res.sort(); Ok(res) }