pub struct Glob<'t> { /* private fields */ }
Expand description
Program that can be matched against paths and directory trees.
Glob
s are constructed from strings called glob expressions that resemble Unix paths
consisting of nominal components delimited by separators. Glob expressions support various
patterns that match and capture specified text in a path. These patterns can be used to
logically match individual paths and to semantically match and walk directory trees.
Examples
A Glob
can be used to determine if a path matches a pattern via the Program
trait.
use wax::{Glob, Program};
let glob = Glob::new("*.png").unwrap();
assert!(glob.is_match("apple.png"));
Patterns form captures, which can be used to isolate matching sub-text.
use wax::{CandidatePath, Glob, Program};
let glob = Glob::new("**/{*.{go,rs}}").unwrap();
let candidate = CandidatePath::from("src/lib.rs");
assert_eq!("lib.rs", glob.matched(&candidate).unwrap().get(2).unwrap());
To match a Glob
against a directory tree, the walk
function can be used to get an
iterator over matching paths.
use wax::walk::Entry;
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());
}
Implementations§
source§impl<'t> Glob<'t>
impl<'t> Glob<'t>
APIs for matching globs against directory trees.
sourcepub fn walk(
&self,
directory: impl Into<PathBuf>
) -> impl 'static + FileIterator<Entry = GlobEntry>
Available on crate feature walk
only.
pub fn walk( &self, directory: impl Into<PathBuf> ) -> impl 'static + FileIterator<Entry = GlobEntry>
walk
only.Gets an iterator over matching file paths in a directory tree.
This function matches a Glob
against a directory tree, returning a FileIterator
that
yields a GlobEntry
for each matching file. Glob
s are the only Program
s that
support this semantic operation; it is not possible to match combinators (Any
) against
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.
The root directory is either the given directory or, if rooted, the invariant
prefix of the Glob
. Either way, this function joins the given
directory with any invariant prefix to potentially begin the walk as far down the tree as
possible. The prefix and any 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. To query the root directory of the walk, see Glob::walker
.
This function uses the default WalkBehavior
. To configure the behavior of the
traversal, see Glob::walk_with_behavior
.
Unlike functions in Program
, this operation is semantic and interacts with the file
system.
Examples
use wax::walk::Entry;
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
combinator can be used
when walking a directory tree to filter entries using patterns. This should generally be
preferred over functions like Iterator::filter
, because it avoids unnecessary reads of
directory trees when matching exhaustive negations.
use wax::walk::{Entry, FileIterator};
use wax::Glob;
let glob = Glob::new("**/*.(?i){jpg,jpeg,png}").unwrap();
for entry in glob
.walk("./Pictures")
.not(["**/(i?){background<s:0,1>,wallpaper<s:0,1>}/**"])
.unwrap()
{
let entry = entry.unwrap();
println!("{:?}", entry.path());
}
sourcepub fn walk_with_behavior(
&self,
directory: impl Into<PathBuf>,
behavior: impl Into<WalkBehavior>
) -> impl 'static + FileIterator<Entry = GlobEntry>
Available on crate feature walk
only.
pub fn walk_with_behavior( &self, directory: impl Into<PathBuf>, behavior: impl Into<WalkBehavior> ) -> impl 'static + FileIterator<Entry = GlobEntry>
walk
only.Gets an iterator over matching files in a directory tree.
This function is the same as Glob::walk
, but it additionally accepts a WalkBehavior
that configures how the traversal interacts with symbolic links, the maximum depth from the
root, etc.
Depth is relative to the root directory of the traversal, which is determined by joining
the given path and any invariant prefix of the Glob
.
See Glob::walk
for more information.
Examples
use wax::walk::{Entry, WalkBehavior};
use wax::Glob;
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
.
use wax::walk::{Entry, LinkBehavior};
use wax::Glob;
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());
}
sourcepub fn walker(&self, directory: impl Into<PathBuf>) -> GlobWalker
Available on crate feature walk
only.
pub fn walker(&self, directory: impl Into<PathBuf>) -> GlobWalker
walk
only.Gets an iterator builder over matching files in a directory tree.
This function gets an intermediate walker that describes iteration over matching files and
provides paths prior to iteration. In particular, walker
can be used when the root
directory of the walk is needed. The root directory may differ from the directory passed
to walking functions.
See Glob::walk
.
Examples
use wax::walk::Entry;
use wax::Glob;
let glob = Glob::new("**/*.{log,txt}").unwrap();
let walker = glob.walker("/var/log");
let root = walker.root_prefix_paths().0.to_path_buf();
for entry in walker.walk() {
let entry = entry.unwrap();
println!("Log: {:?}", entry.path());
}
source§impl<'t> Glob<'t>
impl<'t> Glob<'t>
sourcepub fn new(expression: &'t str) -> Result<Self, BuildError>
pub fn new(expression: &'t str) -> Result<Self, BuildError>
Constructs a Glob
from a glob expression.
A glob expression is UTF-8 encoded text that resembles a Unix path consisting of nominal components delimited by separators and patterns that can be matched against native paths.
Errors
Returns an error if the glob expression fails to build. See BuildError
.
sourcepub fn partition(self) -> (PathBuf, Self)
pub fn partition(self) -> (PathBuf, Self)
Partitions a Glob
into an invariant PathBuf
prefix and variant Glob
postfix.
The invariant prefix contains no glob patterns nor other variant components and therefore
can be interpreted as a native path. The Glob
postfix is variant and contains the
remaining components that follow the prefix. For example, the glob expression
.local/**/*.log
would produce the path .local
and glob **/*.log
. It is possible for
either partition to be empty.
Literal components may be considered variant if they contain characters with casing and the
configured case sensitivity differs from the target platform’s file system. For example,
the case-insensitive literal expression (?i)photos
is considered variant on Unix and
invariant on Windows, because the literal photos
resolves differently in Unix file system
APIs.
Partitioning a Glob
allows any invariant prefix to be used as a native path to
establish a working directory or to interpret semantic components that are not recognized
by globs, such as parent directory ..
components.
Partitioned Glob
s are never rooted. If the glob expression has a root component, then
it is always included in the invariant PathBuf
prefix.
Examples
To match paths against a Glob
while respecting semantic components, the invariant
prefix and candidate path can be canonicalized. The following example canonicalizes both
the working directory joined with the prefix as well as the candidate path and then
attempts to match the Glob
if the candidate path contains the prefix.
use dunce; // Avoids UNC paths on Windows.
use std::path::Path;
use wax::{Glob, Program};
let path: &Path = /* ... */ // Candidate path.
let directory = Path::new("."); // Working directory.
let (prefix, glob) = Glob::new("../../src/**").unwrap().partition();
let prefix = dunce::canonicalize(directory.join(&prefix)).unwrap();
if dunce::canonicalize(path)
.unwrap()
.strip_prefix(&prefix)
.map(|path| glob.is_match(path))
.unwrap_or(false)
{
// ...
}
sourcepub fn into_owned(self) -> Glob<'static>
pub fn into_owned(self) -> Glob<'static>
Clones any borrowed data into an owning instance.
Examples
Glob
s borrow data in the corresponding glob expression. To move a Glob
beyond the scope
of a glob expression, clone the data with this function.
use wax::{BuildError, Glob};
fn local() -> Result<Glob<'static>, BuildError> {
let expression = String::from("**/*.txt");
Glob::new(&expression).map(Glob::into_owned)
}
sourcepub fn captures(&self) -> impl '_ + Clone + Iterator<Item = CapturingToken>
pub fn captures(&self) -> impl '_ + Clone + Iterator<Item = CapturingToken>
Gets metadata for capturing sub-expressions.
This function returns an iterator over capturing tokens, which describe the index and
location of sub-expressions that capture matched text. For example, in the
expression src/**/*.rs
, both **
and *
form captures.
sourcepub fn has_root(&self) -> bool
pub fn has_root(&self) -> bool
Returns true
if the glob has a root.
As with Unix paths, a glob expression has a root if it begins with a separator /
.
Patterns other than separators may also root an expression, such as /**
or </root:1,>
.
sourcepub fn has_semantic_literals(&self) -> bool
pub fn has_semantic_literals(&self) -> bool
Returns true
if the glob has literals that have non-nominal semantics on the target
platform.
The most notable semantic literals are the relative path components .
and ..
, which
refer to a current and parent directory on Unix and Windows operating systems,
respectively. These are interpreted as literals in glob expressions, and so only logically
match paths that contain these exact nominal components (semantic meaning is lost).
See Glob::partition
.
source§impl<'t> Glob<'t>
impl<'t> Glob<'t>
APIs for diagnosing globs.
sourcepub fn diagnosed(expression: &'t str) -> DiagnosticResult<'t, Self>
Available on crate feature miette
only.
pub fn diagnosed(expression: &'t str) -> DiagnosticResult<'t, Self>
miette
only.Constructs a Glob
from a glob expression with diagnostics.
This function is the same as Glob::new
, but additionally returns detailed diagnostics
on both success and failure.
See Glob::diagnose
.
Examples
use tardar::DiagnosticResultExt as _;
use wax::Glob;
let result = Glob::diagnosed("(?i)readme.{md,mkd,markdown}");
for diagnostic in result.diagnostics() {
eprintln!("{}", diagnostic);
}
if let Some(glob) = result.ok_output() { /* ... */ }
sourcepub fn diagnose(&self) -> impl Iterator<Item = Box<dyn Diagnostic + '_>>
Available on crate feature miette
only.
pub fn diagnose(&self) -> impl Iterator<Item = Box<dyn Diagnostic + '_>>
miette
only.Gets non-error Diagnostic
s.
This function requires a receiving Glob
and so does not report error-level
Diagnostic
s. It can be used to get non-error diagnostics after constructing or
partitioning a Glob
.
See Glob::diagnosed
.
Trait Implementations§
source§impl<'t> Program<'t> for Glob<'t>
impl<'t> Program<'t> for Glob<'t>
source§fn is_match<'p>(&self, path: impl Into<CandidatePath<'p>>) -> bool
fn is_match<'p>(&self, path: impl Into<CandidatePath<'p>>) -> bool
true
if a path matches the pattern. Read moresource§fn matched<'p>(&self, path: &'p CandidatePath<'_>) -> Option<MatchedText<'p>>
fn matched<'p>(&self, path: &'p CandidatePath<'_>) -> Option<MatchedText<'p>>
source§fn is_exhaustive(&self) -> bool
fn is_exhaustive(&self) -> bool
true
if the pattern is exhaustive. Read more