#walkdir #glob #glob-pattern #pattern #pattern-matching

fast-glob

A high-performance glob matching crate for Rust

6 releases (3 breaking)

0.4.0 Aug 20, 2024
0.3.3 Aug 15, 2024
0.3.2 Jul 11, 2024
0.2.0 May 30, 2024
0.1.0 May 27, 2024

#179 in Filesystem

Download history 18/week @ 2024-06-03 9/week @ 2024-06-10 369/week @ 2024-07-08 318/week @ 2024-07-15 190/week @ 2024-07-22 403/week @ 2024-07-29 179/week @ 2024-08-05 358/week @ 2024-08-12 499/week @ 2024-08-19 521/week @ 2024-08-26 482/week @ 2024-09-02 1149/week @ 2024-09-09 2534/week @ 2024-09-16

4,721 downloads per month
Used in 22 crates (4 directly)

MIT license

19KB
292 lines

fast-glob

Introduce

A high-performance glob matching crate for Rust based on devongovett/glob-match.

Key Features:

  • Up to 60% performance improvement.
  • Supports more complete and well-rounded features.

Examples

use fast_glob::glob_match;

let glob = "some/**/n*d[k-m]e?txt";
let path = "some/a/bigger/path/to/the/crazy/needle.txt";

assert!(glob_match(glob, path));

Syntax

Syntax Meaning
? Matches any single character.
* Matches zero or more characters, except for path separators (e.g. /).
** Matches zero or more characters, including path separators. Must match a complete path segment (i.e. followed by a / or the end of the pattern).
[ab] Matches one of the characters contained in the brackets. Character ranges, e.g. [a-z] are also supported. Use [!ab] or [^ab] to match any character except those contained in the brackets.
{a,b} Matches one of the patterns contained in the braces. Any of the wildcard characters can be used in the sub-patterns. Braces may be nested up to 10 levels deep.
! When at the start of the glob, this negates the result. Multiple ! characters negate the glob multiple times.
\ A backslash character may be used to escape any of the above special characters.

Benchmark

Test Case 1

const GLOB: &'static str = "some/**/n*d[k-m]e?txt";
const PATH: &'static str = "some/a/bigger/path/to/the/crazy/needle.txt";
mine                       time:   [83.742 ns 84.400 ns 85.132 ns]
glob                       time:   [386.77 ns 396.19 ns 406.87 ns]
globset                    time:   [21.010 µs 21.114 µs 21.225 µs]
glob_match                 time:   [195.58 ns 196.80 ns 198.24 ns]
glob_pre_compiled          time:   [88.180 ns 90.274 ns 92.158 ns]
globset_pre_compiled       time:   [42.680 ns 42.778 ns 42.911 ns]

Test Case 2

const GLOB: &'static str = "some/**/{tob,crazy}/?*.{png,txt}";
const PATH: &'static str = "some/a/bigger/path/to/the/crazy/needle.txt";
mine                       time:   [309.80 ns 311.56 ns 313.25 ns]
globset                    time:   [31.456 µs 31.502 µs 31.559 µs]
glob_match                 time:   [384.21 ns 384.71 ns 385.15 ns]
globset_pre_compiled       time:   [42.505 ns 42.526 ns 42.551 ns]

FAQ

Why not use the more efficient glob_match for brace expansion?

glob_match is unable to handle complex brace expansions. Below are some failed examples:

  • glob_match("{a/b,a/b/c}/c", "a/b/c")
  • glob_match("**/foo{bar,b*z}", "foobuzz")
  • glob_match("**/{a,b}/c.png", "some/a/b/c.png")

Due to these limitations, brace expansion requires a different implementation that can handle the complexity of such patterns, resulting in some performance trade-offs.

Credits

No runtime deps