From 3cdbe6651b8b4b56231ad2088e210b23d58bae30 Mon Sep 17 00:00:00 2001 From: Sean Olson Date: Wed, 8 Nov 2023 12:14:15 -0800 Subject: [PATCH] Reintroduce the original documentation for `Glob::walk`. --- src/walk/glob.rs | 114 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/src/walk/glob.rs b/src/walk/glob.rs index eac6176..68e7775 100644 --- a/src/walk/glob.rs +++ b/src/walk/glob.rs @@ -11,6 +11,76 @@ use crate::walk::{EntryResidue, FileIterator, PathExt as _, TreeEntry, WalkBehav use crate::{BuildError, CandidatePath, Combine, Glob}; impl<'t> Glob<'t> { + /// Gets an iterator over matching files in a directory tree. + /// + /// This function matches a [`Glob`] against a directory tree, returning each matching file as + /// a [`WalkEntry`]. [`Glob`]s are the only patterns that support this semantic operation; it + /// is not possible to match combinators over directory trees. + /// + /// As with [`Path::join`] and [`PathBuf::push`], the base directory can be escaped or + /// overridden by rooted [`Glob`]s. In many cases, the current working directory `.` is an + /// appropriate base directory and will be intuitively ignored if the [`Glob`] is rooted, such + /// as in `/mnt/media/**/*.mp4`. The [`has_root`] function can be used to check if a [`Glob`] + /// is rooted and the [`Walk::root`] function can be used to get the resulting root directory + /// of the traversal. + /// + /// The [root directory][`Walk::root`] is established via the [invariant + /// prefix][`Glob::partition`] of the [`Glob`]. **The prefix and any [semantic + /// literals][`Glob::has_semantic_literals`] in this prefix are interpreted semantically as a + /// path**, so components like `.` and `..` that precede variant patterns interact with the + /// base directory semantically. This means that expressions like `../**` escape the base + /// directory as expected on Unix and Windows, for example. + /// + /// This function uses the default [`WalkBehavior`]. To configure the behavior of the + /// traversal, see [`Glob::walk_with_behavior`]. + /// + /// Unlike functions in [`Pattern`], **this operation is semantic and interacts with the file + /// system**. + /// + /// # Examples + /// + /// ```rust,no_run + /// use wax::Glob; + /// + /// let glob = Glob::new("**/*.(?i){jpg,jpeg}").unwrap(); + /// for entry in glob.walk("./Pictures") { + /// let entry = entry.unwrap(); + /// println!("JPEG: {:?}", entry.path()); + /// } + /// ``` + /// + /// Glob expressions do not support general negations, but the [`not`] iterator adaptor can be + /// used when walking a directory tree to filter [`WalkEntry`]s using arbitary patterns. **This + /// should generally be preferred over functions like [`Iterator::filter`], because it avoids + /// unnecessary reads of directory trees when matching [exhaustive + /// negations][`Pattern::is_exhaustive`].** + /// + /// ```rust,no_run + /// use wax::Glob; + /// + /// let glob = Glob::new("**/*.(?i){jpg,jpeg,png}").unwrap(); + /// for entry in glob + /// .walk("./Pictures") + /// .not(["**/(i?){background,wallpaper}/**"]) + /// .unwrap() + /// { + /// let entry = entry.unwrap(); + /// println!("{:?}", entry.path()); + /// } + /// ``` + /// + /// [`Glob`]: crate::Glob + /// [`Glob::walk_with_behavior`]: crate::Glob::walk_with_behavior + /// [`has_root`]: crate::Glob::has_root + /// [`Iterator::filter`]: std::iter::Iterator::filter + /// [`not`]: crate::Walk::not + /// [`Path::join`]: std::path::Path::join + /// [`PathBuf::push`]: std::path::PathBuf::push + /// [`Pattern`]: crate::Pattern + /// [`Pattern::is_exhaustive`]: crate::Pattern::is_exhaustive + /// [`Walk::root`]: crate::Walk::root + /// [`WalkBehavior`]: crate::WalkBehavior + /// [`WalkEntry`]: crate::WalkEntry #[cfg_attr(docsrs, doc(cfg(feature = "walk")))] pub fn walk( &self, @@ -19,6 +89,50 @@ impl<'t> Glob<'t> { self.walk_with_behavior(directory, WalkBehavior::default()) } + /// Gets an iterator over matching files in a directory tree. + /// + /// This function is the same as [`Glob::walk`], but it additionally accepts a + /// [`WalkBehavior`]. This can be used to configure how the traversal interacts with symbolic + /// links, the maximum depth from the root, etc. + /// + /// Depth is relative to the [root directory][`Walk::root`] of the traversal, which is + /// determined by joining the given path and any [invariant prefix][`Glob::partition`] of the + /// [`Glob`]. + /// + /// See [`Glob::walk`] for more information. + /// + /// # Examples + /// + /// ```rust,no_run + /// use wax::{Glob, WalkBehavior}; + /// + /// let glob = Glob::new("**/*.(?i){jpg,jpeg}").unwrap(); + /// for entry in glob.walk_with_behavior("./Pictures", WalkBehavior::default()) { + /// let entry = entry.unwrap(); + /// println!("JPEG: {:?}", entry.path()); + /// } + /// ``` + /// + /// By default, symbolic links are read as normal files and their targets are ignored. To + /// follow symbolic links and traverse any directories that they reference, specify a + /// [`LinkBehavior`]. + /// + /// ```rust,no_run + /// use wax::{Glob, LinkBehavior}; + /// + /// let glob = Glob::new("**/*.txt").unwrap(); + /// for entry in glob.walk_with_behavior("/var/log", LinkBehavior::ReadTarget) { + /// let entry = entry.unwrap(); + /// println!("Log: {:?}", entry.path()); + /// } + /// ``` + /// + /// [`Glob`]: crate::Glob + /// [`Glob::partition`]: crate::Glob::partition + /// [`Glob::walk`]: crate::Glob::walk + /// [`LinkBehavior`]: crate::LinkBehavior + /// [`Walk::root`]: crate::Walk::root + /// [`WalkBehavior`]: crate::WalkBehavior #[cfg_attr(docsrs, doc(cfg(feature = "walk")))] pub fn walk_with_behavior( &self,