pub struct PatternSet { /* private fields */ }Expand description
A list of compiled Patterns matched as one, the counterpart of
globset::GlobSet.
Every query answers exactly what asking the members one by one would: the
is_match* methods are the OR of the members’ verdicts, and the
matches*_into methods list each member that matches, by its position in
the list the set was built from. The three pairs mirror the three
Pattern entry points, so a set reads its patterns the way a single
pattern would be read.
The set is faster than a loop because it asks only the members a path can
possibly satisfy. Literal extensions, whole literal components, and fixed
prefixes and suffixes are indexed once at construction, so a list of
hundreds of **/*.ext, dir/** and **/name/** globs costs a few hash
lookups per path rather than hundreds of matches. Patterns without such a
literal, such as * or an extglob, are asked for every path, as they
would be in a loop.
use ferralk_glob::{PatternOptions, PatternSet};
let set = PatternSet::new(
["**/*.rs", "**/node_modules/**", "docs/*.md"],
PatternOptions::walker(),
)?;
assert!(set.is_match_glob_path("src/lib.rs"));
assert!(set.is_match_glob_path("web/node_modules/left-pad/index.js"));
assert!(!set.is_match_glob_path("docs/api/index.md"));
// Which members matched, by their index in the input list.
let mut matched = Vec::new();
set.matches_glob_path_into("node_modules/pkg/build.rs", &mut matched);
assert_eq!(matched, [0, 1]);Members may carry different PatternOptions: compile each Pattern
yourself and collect them.
use ferralk_glob::{Pattern, PatternOptions, PatternSet};
let options = PatternOptions::walker();
let set: PatternSet = [
Pattern::compile("**/*.rs", options)?,
// Only this member folds ASCII case.
Pattern::compile("**/README.md", options.case_insensitive(true))?,
]
.into_iter()
.collect();
assert!(set.is_match_glob_path("docs/readme.MD"));
assert!(!set.is_match_glob_path("src/LIB.RS"));Implementations§
Source§impl PatternSet
impl PatternSet
Sourcepub fn new<I>(
patterns: I,
options: PatternOptions,
) -> Result<Self, PatternSetError>
pub fn new<I>( patterns: I, options: PatternOptions, ) -> Result<Self, PatternSetError>
Compiles every glob with the same options, keeping their order.
use ferralk_glob::{PatternOptions, PatternSet};
let excludes = PatternSet::new(["**/target/**", "**/*.tmp"], PatternOptions::walker())?;
assert!(excludes.is_match_glob_path("crates/cli/target/debug/cli"));
assert!(!excludes.is_match_glob_path("crates/cli/src/main.rs"));§Errors
Returns a PatternSetError for the first glob that does not compile.
PatternSetError::index is that glob’s position in patterns, and
PatternSetError::pattern_error the PatternError that
Pattern::compile reported for it.
use ferralk_glob::{PatternOptions, PatternSet};
let error = PatternSet::new(["src/**", "[a-", "*.md"], PatternOptions::walker())
.expect_err("the class is never closed");
assert_eq!(error.index(), 1);
assert_eq!(error.pattern_error().offset(), 0);Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
The number of member patterns.
use ferralk_glob::{PatternOptions, PatternSet};
let set = PatternSet::new(["*.rs", "*.toml"], PatternOptions::walker())?;
assert_eq!(set.len(), 2);Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Whether the set has no members. An empty set matches nothing.
use ferralk_glob::PatternSet;
let set = PatternSet::default();
assert!(set.is_empty());
assert!(!set.is_match_glob_path("anything"));Sourcepub fn is_match(&self, path: impl AsRef<[u8]>) -> bool
pub fn is_match(&self, path: impl AsRef<[u8]>) -> bool
Whether any member’s Pattern::is_match accepts path: the whole
byte sequence, with wildcards crossing /.
use ferralk_glob::{PatternOptions, PatternSet};
let set = PatternSet::new(["*.rs", "*.toml"], PatternOptions::walker())?;
// `*` crosses the separator under this entry point.
assert!(set.is_match("src/lib.rs"));
assert!(!set.is_match("src/lib.c"));Sourcepub fn is_match_path(&self, path: impl AsRef<[u8]>) -> bool
pub fn is_match_path(&self, path: impl AsRef<[u8]>) -> bool
Whether any member’s Pattern::is_match_path accepts path, under
zlob’s list-filter rule.
use ferralk_glob::{PatternOptions, PatternSet};
let set = PatternSet::new(["*.rs", "docs/*.md"], PatternOptions::walker())?;
// A wildcard in the first component crosses separators...
assert!(set.is_match_path("./src/lib.rs"));
// ...one directly behind `/` does not.
assert!(!set.is_match_path("docs/api/index.md"));Sourcepub fn is_match_glob_path(&self, path: impl AsRef<[u8]>) -> bool
pub fn is_match_glob_path(&self, path: impl AsRef<[u8]>) -> bool
Whether any member’s Pattern::is_match_glob_path accepts path,
with every ordinary wildcard inside one component as in a shell. This
is the entry point for root-relative filesystem paths.
use ferralk_glob::{PatternOptions, PatternSet};
let set = PatternSet::new(["*.toml", "src/**/*.rs"], PatternOptions::walker())?;
assert!(set.is_match_glob_path("Cargo.toml"));
assert!(set.is_match_glob_path("./src/bin/main.rs"));
// `*` stays in its component.
assert!(!set.is_match_glob_path("crates/cli/Cargo.toml"));Sourcepub fn matches_into(&self, path: impl AsRef<[u8]>, matches: &mut Vec<usize>)
pub fn matches_into(&self, path: impl AsRef<[u8]>, matches: &mut Vec<usize>)
Replaces the contents of matches with the index of every member
whose Pattern::is_match accepts path, in ascending order.
The vector is cleared first and reused, so a caller that asks about many paths allocates only while it grows.
use ferralk_glob::{PatternOptions, PatternSet};
let set = PatternSet::new(["*.rs", "src/*", "*.md"], PatternOptions::walker())?;
let mut matches = Vec::new();
set.matches_into("src/lib.rs", &mut matches);
assert_eq!(matches, [0, 1]);Sourcepub fn matches_path_into(
&self,
path: impl AsRef<[u8]>,
matches: &mut Vec<usize>,
)
pub fn matches_path_into( &self, path: impl AsRef<[u8]>, matches: &mut Vec<usize>, )
Replaces the contents of matches with the index of every member
whose Pattern::is_match_path accepts path, in ascending order.
The vector is cleared first.
use ferralk_glob::{PatternOptions, PatternSet};
let set = PatternSet::new(["*.rs", "src/*.rs", "*.md"], PatternOptions::walker())?;
let mut matches = Vec::new();
set.matches_path_into("./src/bin/main.rs", &mut matches);
// `src/*.rs` keeps its `*` inside `bin/`, which holds a separator.
assert_eq!(matches, [0]);Sourcepub fn matches_glob_path_into(
&self,
path: impl AsRef<[u8]>,
matches: &mut Vec<usize>,
)
pub fn matches_glob_path_into( &self, path: impl AsRef<[u8]>, matches: &mut Vec<usize>, )
Replaces the contents of matches with the index of every member
whose Pattern::is_match_glob_path accepts path, in ascending
order. The vector is cleared first.
use ferralk_glob::{PatternOptions, PatternSet};
let rules = ["**/*.ts", "**/*.test.ts", "src/generated/**"];
let set = PatternSet::new(rules, PatternOptions::walker())?;
let mut matches = Vec::new();
set.matches_glob_path_into("src/generated/api.test.ts", &mut matches);
assert_eq!(matches, [0, 1, 2]);
// The last matching rule wins, as in many configuration formats.
set.matches_glob_path_into("src/app.ts", &mut matches);
assert_eq!(matches.last().map(|&index| rules[index]), Some("**/*.ts"));Trait Implementations§
Source§impl Clone for PatternSet
impl Clone for PatternSet
Source§impl Debug for PatternSet
impl Debug for PatternSet
Source§impl Default for PatternSet
impl Default for PatternSet
Source§impl FromIterator<Pattern> for PatternSet
impl FromIterator<Pattern> for PatternSet
Source§fn from_iter<I: IntoIterator<Item = Pattern>>(patterns: I) -> Self
fn from_iter<I: IntoIterator<Item = Pattern>>(patterns: I) -> Self
Collects compiled patterns into a set, keeping their order and each
member’s own PatternOptions.
use ferralk_glob::{Pattern, PatternOptions, PatternSet};
let set: PatternSet = ["*.rs", "*.toml"]
.iter()
.map(|glob| Pattern::compile(glob, PatternOptions::walker()))
.collect::<Result<_, _>>()?;
assert!(set.is_match_glob_path("Cargo.toml"));