pub struct Glob<'t> { /* private fields */ }
Expand description
Pattern 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 Pattern
trait.
use wax::{Glob, Pattern};
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, Pattern};
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::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>
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 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 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, Pattern};
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 walk(&self, directory: impl AsRef<Path>) -> Walk<'_> ⓘ
Available on crate feature walk
only.
pub fn walk(&self, directory: impl AsRef<Path>) -> Walk<'_> ⓘ
walk
only.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 is established via the invariant
prefix of the Glob
. 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.
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
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.
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 AsRef<Path>,
behavior: impl Into<WalkBehavior>,
) -> Walk<'_> ⓘ
Available on crate feature walk
only.
pub fn walk_with_behavior( &self, directory: impl AsRef<Path>, behavior: impl Into<WalkBehavior>, ) -> Walk<'_> ⓘ
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
. 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 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::{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
.
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());
}
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
.
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
.
Trait Implementations§
Source§impl<'t> Pattern<'t> for Glob<'t>
impl<'t> Pattern<'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 moreAuto Trait Implementations§
impl<'t> Freeze for Glob<'t>
impl<'t> RefUnwindSafe for Glob<'t>
impl<'t> Send for Glob<'t>
impl<'t> Sync for Glob<'t>
impl<'t> Unpin for Glob<'t>
impl<'t> UnwindSafe for Glob<'t>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more