Skip to main content

Pattern

Struct Pattern 

Source
pub struct Pattern { /* private fields */ }
Expand description

A compiled glob pattern.

Implementations§

Source§

impl Pattern

Source

pub fn has_wildcards(pattern: impl AsRef<[u8]>, options: PatternOptions) -> bool

Reports whether the enabled syntax options make a pattern non-literal.

This is a byte-first preflight helper. Like zlob’s hasWildcards, it deliberately reports syntax markers even when an escape option would later make a particular marker literal.

Source

pub fn compile( pattern: impl AsRef<[u8]>, options: PatternOptions, ) -> Result<Self, PatternError>

Compiles a pattern once for repeated matching against raw path bytes.

use ferralk_glob::{Pattern, PatternOptions};

let source_file = Pattern::compile("src/**/*.{rs,toml}", PatternOptions::walker())?;

assert!(source_file.is_match_glob_path("src/lib.rs"));
assert!(!source_file.is_match_glob_path("src/generated/lib.rs.bak"));
§Errors

Returns a PatternError when the pattern is not valid under options: an unclosed class or extglob group, an invalid range, or a pattern beyond the compile budget. PatternError::offset locates the problem in the caller’s pattern bytes.

Source

pub fn validate( pattern: impl AsRef<[u8]>, options: PatternOptions, ) -> Result<(), PatternError>

Reports whether a pattern is syntactically valid without retaining it.

§Errors

Returns the same PatternError that Pattern::compile would.

Source

pub fn is_match(&self, path: impl AsRef<[u8]>) -> bool

Matches the entire candidate byte sequence. Ordinary wildcards may cross separators, and a leading ./ is compared literally.

Use it for text in which / is not special. For a filesystem path, Self::is_match_glob_path is usually the entry point you want; the same three candidates are shown on each of the three.

use ferralk_glob::{Pattern, PatternOptions};

let pattern = Pattern::compile("*.rs", PatternOptions::walker())?;

assert!(pattern.is_match("lib.rs"));
// `*` crosses the separator.
assert!(pattern.is_match("src/lib.rs"));
// `./` is compared literally, and `*` does not cover its leading period.
assert!(!pattern.is_match("./lib.rs"));

Extglob patterns that fall back to the retained interpreter can still spend quadratic time on one adversarially long component. For untrusted path-shaped input, prefer a component-scoped entry point such as Self::is_match_path where that matches the caller’s semantics.

Source

pub fn filter_paths<'a, T>( &self, paths: impl IntoIterator<Item = &'a T>, ) -> Vec<&'a T>
where T: AsRef<[u8]> + ?Sized + 'a,

Returns the input paths accepted by this compiled pattern, in input order. Wildcards after an explicit separator stay within that path component; recursive ** is the separator-crossing form. The returned references borrow the caller-owned path list.

Each path is asked through Self::is_match_path, zlob’s list rule, under which a wildcard in the first component crosses separators. For shell semantics, filter with Self::is_match_glob_path yourself:

use ferralk_glob::{Pattern, PatternOptions};

let paths = ["lib.rs", "src/lib.rs", "src/bin/main.rs", "README.md"];

// A wildcard directly behind `/` stays in its component...
let direct = Pattern::compile("src/*.rs", PatternOptions::walker())?;
assert_eq!(direct.filter_paths(&paths), [&"src/lib.rs"]);

// ...while one in the first component crosses separators.
let top = Pattern::compile("*.rs", PatternOptions::walker())?;
assert_eq!(
    top.filter_paths(&paths),
    [&"lib.rs", &"src/lib.rs", &"src/bin/main.rs"],
);

// Shell semantics: `*.rs` names the top level only.
let shell: Vec<_> = paths
    .iter()
    .filter(|path| top.is_match_glob_path(path))
    .collect();
assert_eq!(shell, [&"lib.rs"]);
Source

pub fn is_match_path(&self, path: impl AsRef<[u8]>) -> bool

Matches one root-relative path with the zlob list-filter policy used by Pattern::filter_paths. A root wildcard may cross separators, while wildcards after an explicit separator are component-local. One leading ./ is ignored on both the pattern and candidate.

use ferralk_glob::{Pattern, PatternOptions};

let pattern = Pattern::compile("*.rs", PatternOptions::walker())?;

assert!(pattern.is_match_path("lib.rs"));
// A wildcard in the first component crosses the separator.
assert!(pattern.is_match_path("src/lib.rs"));
// One leading `./` is ignored.
assert!(pattern.is_match_path("./lib.rs"));

// A wildcard directly behind `/` stays in its component.
let nested = Pattern::compile("src/*.rs", PatternOptions::walker())?;
assert!(!nested.is_match_path("src/bin/main.rs"));
Source

pub fn is_match_glob_path(&self, path: impl AsRef<[u8]>) -> bool

Matches one root-relative filesystem-glob path. Every ordinary wildcard stays within its path component; recursive ** remains the separator-crossing form. This is stricter than Pattern::is_match_path at the root component and is suitable for traversal filters. One leading ./ is ignored on both the pattern and candidate.

This is how a shell and the ferralk walker read a pattern, and the entry point to use for a path relative to where the pattern is anchored. Pass a Path as path_bytes(path).

use ferralk_glob::{Pattern, PatternOptions};

let pattern = Pattern::compile("*.rs", PatternOptions::walker())?;

assert!(pattern.is_match_glob_path("lib.rs"));
// `*` stays in one component; write `**/*.rs` for every depth.
assert!(!pattern.is_match_glob_path("src/lib.rs"));
// One leading `./` is ignored.
assert!(pattern.is_match_glob_path("./lib.rs"));

let recursive = Pattern::compile("**/*.rs", PatternOptions::walker())?;
assert!(recursive.is_match_glob_path("lib.rs"));
assert!(recursive.is_match_glob_path("src/lib.rs"));
Source

pub fn filter_paths_at<'a, T>( &self, base_path: impl AsRef<[u8]>, paths: impl IntoIterator<Item = &'a T>, ) -> Vec<&'a T>
where T: AsRef<[u8]> + ?Sized + 'a,

Returns the input paths accepted relative to base_path, preserving the original full paths and caller order. Candidates outside the base directory are ignored.

use ferralk_glob::{Pattern, PatternOptions};

let pattern = Pattern::compile("src/*.rs", PatternOptions::walker())?;
let paths = [
    "crates/app/src/lib.rs",
    "crates/app/README.md",
    "crates/cli/src/main.rs",
    "crates/application/src/lib.rs",
];

// Each path is matched below the base and returned in full; a path
// outside it, `crates/application` included, is left out.
assert_eq!(
    pattern.filter_paths_at("crates/app", &paths),
    [&"crates/app/src/lib.rs"],
);
Source

pub fn filter_path_indices<'a, T>( &self, paths: impl IntoIterator<Item = &'a T>, ) -> Vec<usize>
where T: AsRef<[u8]> + ?Sized + 'a,

Returns the indices of input paths accepted by this compiled pattern, in their original input order.

Useful when the paths live beside other data, such as a list of records, and the caller wants positions rather than borrowed paths.

use ferralk_glob::{Pattern, PatternOptions};

let pattern = Pattern::compile("src/**/*.rs", PatternOptions::walker())?;
let files = ["README.md", "src/lib.rs", "src/bin/main.rs"].map(String::from);

assert_eq!(pattern.filter_path_indices(&files), [1, 2]);
Source

pub fn filter_path_indices_at<'a, T>( &self, base_path: impl AsRef<[u8]>, paths: impl IntoIterator<Item = &'a T>, ) -> Vec<usize>
where T: AsRef<[u8]> + ?Sized + 'a,

Returns the indices of full input paths accepted relative to base_path, in their original input order.

use ferralk_glob::{Pattern, PatternOptions};

let pattern = Pattern::compile("*.toml", PatternOptions::walker())?;
let paths = ["crates/app/Cargo.toml", "Cargo.toml", "crates/app/src/x.toml"];

// `Cargo.toml` is outside the base. `src/x.toml` is selected because a
// wildcard in the first component crosses separators under the list
// rule of `filter_paths`.
assert_eq!(pattern.filter_path_indices_at("crates/app", &paths), [0, 2]);

Trait Implementations§

Source§

impl Clone for Pattern

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 Pattern

Source§

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

Formats the value using the given formatter. 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.