use std::env; use std::error; use std::fs::{self, File}; use std::io; use std::path::{Path, PathBuf}; use std::result;
usecrate::{DirEntry, Error};
/// Create an error from a format!-like syntax. #[macro_export]
macro_rules! err {
($($tt:tt)*) => { Box::<dyn error::Error + Send + Sync>::from(format!($($tt)*))
}
}
/// A convenient result type alias. pubtype Result<T> = result::Result<T, Box<dyn error::Error + Send + Sync>>;
/// The result of running a recursive directory iterator on a single directory. #[derive(Debug)] pubstruct RecursiveResults {
ents: Vec<DirEntry>,
errs: Vec<Error>,
}
impl RecursiveResults { /// Return all of the errors encountered during traversal. pubfn errs(&self) -> &[Error] {
&self.errs
}
/// Assert that no errors have occurred. pubfn assert_no_errors(&self) {
assert!( self.errs.is_empty(), "expected to find no errors, but found: {:?}", self.errs
);
}
/// Return all the successfully retrieved directory entries in the order /// in which they were retrieved. pubfn ents(&self) -> &[DirEntry] {
&self.ents
}
/// Return all paths from all successfully retrieved directory entries. /// /// This does not include paths that correspond to an error. pubfn paths(&self) -> Vec<PathBuf> { self.ents.iter().map(|d| d.path().to_path_buf()).collect()
}
/// Return all the successfully retrieved directory entries, sorted /// lexicographically by their full file path. pubfn sorted_ents(&self) -> Vec<DirEntry> { letmut ents = self.ents.clone();
ents.sort_by(|e1, e2| e1.path().cmp(e2.path()));
ents
}
/// Return all paths from all successfully retrieved directory entries, /// sorted lexicographically. /// /// This does not include paths that correspond to an error. pubfn sorted_paths(&self) -> Vec<PathBuf> { self.sorted_ents().into_iter().map(|d| d.into_path()).collect()
}
}
/// A helper for managing a directory in which to run tests. /// /// When manipulating paths within this directory, paths are interpreted /// relative to this directory. #[derive(Debug)] pubstruct Dir {
dir: TempDir,
}
impl Dir { /// Create a new empty temporary directory. pubfn tmp() -> Dir { let dir = TempDir::new().unwrap();
Dir { dir }
}
/// Return the path to this directory. pubfn path(&self) -> &Path { self.dir.path()
}
/// Return a path joined to the path to this directory. pubfn join<P: AsRef<Path>>(&self, path: P) -> PathBuf { self.path().join(path)
}
/// Run the given iterator and return the result as a distinct collection /// of directory entries and errors. pubfn run_recursive<I>(&self, it: I) -> RecursiveResults where
I: IntoIterator<Item = result::Result<DirEntry, Error>>,
{ letmut results = RecursiveResults { ents: vec![], errs: vec![] }; for result in it { match result {
Ok(ent) => results.ents.push(ent),
Err(err) => results.errs.push(err),
}
}
results
}
/// Create a directory at the given path, while creating all intermediate /// directories as needed. pubfn mkdirp<P: AsRef<Path>>(&self, path: P) { let full = self.join(path);
fs::create_dir_all(&full)
.map_err(|e| {
err!("failed to create directory {}: {}", full.display(), e)
})
.unwrap();
}
/// Create an empty file at the given path. All ancestor directories must /// already exists. pubfn touch<P: AsRef<Path>>(&self, path: P) { let full = self.join(path);
File::create(&full)
.map_err(|e| {
err!("failed to create file {}: {}", full.display(), e)
})
.unwrap();
}
/// Create empty files at the given paths. All ancestor directories must /// already exists. pubfn touch_all<P: AsRef<Path>>(&self, paths: &[P]) { for p in paths { self.touch(p);
}
}
/// Create a file symlink to the given src with the given link name. pubfn symlink_file<P1: AsRef<Path>, P2: AsRef<Path>>(
&self,
src: P1,
link_name: P2,
) { #[cfg(windows)] fn imp(src: &Path, link_name: &Path) -> io::Result<()> { use std::os::windows::fs::symlink_file;
symlink_file(src, link_name)
}
let (src, link_name) = (self.join(src), self.join(link_name));
imp(&src, &link_name)
.map_err(|e| {
err!( "failed to symlink file {} with target {}: {}",
src.display(),
link_name.display(),
e
)
})
.unwrap()
}
/// Create a directory symlink to the given src with the given link name. pubfn symlink_dir<P1: AsRef<Path>, P2: AsRef<Path>>(
&self,
src: P1,
link_name: P2,
) { #[cfg(windows)] fn imp(src: &Path, link_name: &Path) -> io::Result<()> { use std::os::windows::fs::symlink_dir;
symlink_dir(src, link_name)
}
let (src, link_name) = (self.join(src), self.join(link_name));
imp(&src, &link_name)
.map_err(|e| {
err!( "failed to symlink directory {} with target {}: {}",
src.display(),
link_name.display(),
e
)
})
.unwrap()
}
}
/// A simple wrapper for creating a temporary directory that is automatically /// deleted when it's dropped. /// /// We use this in lieu of tempfile because tempfile brings in too many /// dependencies. #[derive(Debug)] pubstruct TempDir(PathBuf);
impl Drop for TempDir { fn drop(&mutself) {
fs::remove_dir_all(&self.0).unwrap();
}
}
impl TempDir { /// Create a new empty temporary directory under the system's configured /// temporary directory. pubfn new() -> Result<TempDir> { #[allow(deprecated)] use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
let tmpdir = env::temp_dir(); for _ in0..TRIES { let count = COUNTER.fetch_add(1, Ordering::SeqCst); let path = tmpdir.join("rust-walkdir").join(count.to_string()); if path.is_dir() { continue;
}
fs::create_dir_all(&path).map_err(|e| {
err!("failed to create {}: {}", path.display(), e)
})?; return Ok(TempDir(path));
}
Err(err!("failed to create temp dir after {} tries", TRIES))
}
/// Return the underlying path to this temporary directory. pubfn path(&self) -> &Path {
&self.0
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-06-18)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.