Skip to main content

PatternSet

Struct PatternSet 

Source
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

Source

pub fn new<I>( patterns: I, options: PatternOptions, ) -> Result<Self, PatternSetError>
where I: IntoIterator, I::Item: AsRef<[u8]>,

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);
Source

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);
Source

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"));
Source

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"));
Source

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"));
Source

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"));
Source

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]);
Source

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]);
Source

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

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PatternSet

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for PatternSet

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl FromIterator<Pattern> for PatternSet

Source§

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"));

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.