| Crates.io | scribe-patterns |
| lib.rs | scribe-patterns |
| version | 0.5.1 |
| created_at | 2025-09-13 06:23:47.195818+00 |
| updated_at | 2025-12-01 20:15:35.919281+00 |
| description | Advanced pattern matching and search algorithms for Scribe |
| homepage | https://github.com/sibyllinesoft/scribe |
| repository | https://github.com/sibyllinesoft/scribe |
| max_upload_size | |
| id | 1837304 |
| size | 174,199 |
Advanced pattern matching and filtering for Scribe repository analysis.
scribe-patterns provides sophisticated pattern matching capabilities for file selection, filtering, and search operations. It handles glob patterns, regex matching, .gitignore semantics, and custom ignore rules with high performance and correct edge case handling.
*, **, ?, [abc], {a,b,c}**/ for recursive directory traversal!pattern to exclude specific files.gitignore parsing: Full compatibility with Git's ignore rules! negation patterns/pattern from pattern/# are ignored.scribeignore: Scribe-specific ignore patternsPattern Input → Parser → Compiled Matcher → Match Engine
↓ ↓ ↓ ↓
Glob/Regex Validate globset/regex Apply to Paths
Strings Syntax Compilation Fast Matching
PatternSetCollection of patterns with unified matching interface:
*.rs, **/*.pyIgnoreBuilderConstructs ignore rule sets from multiple sources:
.gitignore files: Standard Git ignore semantics.scribeignore files: Scribe-specific patternsPathMatcherEfficient path matching against pattern sets:
PatternParserParses and validates pattern syntax:
\*, \?, etc.use scribe_patterns::{PatternSet, PathMatcher};
let patterns = PatternSet::from_globs(vec![
"**/*.rs", // All Rust files
"**/*.py", // All Python files
"!**/*_test.py", // Except test files
])?;
let matcher = PathMatcher::new(patterns);
assert!(matcher.is_match("src/main.rs"));
assert!(matcher.is_match("lib/utils.py"));
assert!(!matcher.is_match("lib/utils_test.py")); // Negated
use scribe_patterns::IgnoreBuilder;
let mut builder = IgnoreBuilder::new("/path/to/repo");
builder.add_gitignore(".gitignore")?;
builder.add_custom("target/**")?; // Exclude Rust build directory
builder.add_custom("!target/debug/important.txt")?; // But include this file
let ignore = builder.build()?;
for entry in walkdir::WalkDir::new("/path/to/repo") {
let entry = entry?;
if ignore.matched(entry.path(), entry.file_type().is_dir()).is_ignore() {
continue; // Skip ignored files
}
// Process file
}
use scribe_patterns::{PatternSet, Matcher};
// Include patterns
let include = PatternSet::from_globs(vec![
"src/**/*.rs",
"lib/**/*.rs",
])?;
// Exclude patterns
let exclude = PatternSet::from_globs(vec![
"**/target/**",
"**/*.bak",
])?;
let matcher = Matcher::new()
.include(include)
.exclude(exclude);
// File must match include AND not match exclude
if matcher.should_include("src/utils.rs") {
// Process file
}
use scribe_patterns::PatternSet;
let patterns = PatternSet::from_regex(vec![
r".*_test\.(rs|py)$", // Test files in Rust or Python
r"^src/.*/mod\.rs$", // All mod.rs files in src
])?;
assert!(patterns.is_match("src/utils/mod.rs"));
assert!(patterns.is_match("lib/parser_test.py"));
use scribe_patterns::{PatternSet, MatchOptions};
let patterns = PatternSet::from_globs(vec!["*.TXT", "*.Md"])?;
let options = MatchOptions {
case_sensitive: false,
..Default::default()
};
let matcher = PathMatcher::new(patterns).with_options(options);
assert!(matcher.is_match("readme.md")); // Matches *.Md
assert!(matcher.is_match("notes.txt")); // Matches *.TXT
| Pattern | Matches | Example |
|---|---|---|
* |
Any string (not /) |
*.rs → main.rs, lib.rs |
** |
Any path segment | **/*.py → a/b/c.py |
? |
Single character | ?.txt → a.txt, 1.txt |
[abc] |
Character set | [abc].rs → a.rs, b.rs |
{a,b} |
Alternatives | *.{rs,py} → main.rs, util.py |
!pattern |
Negation | !test*.py → exclude test files |
| Pattern | Behavior |
|---|---|
pattern |
Matches in any directory |
/pattern |
Matches only at root |
dir/ |
Matches directory only |
!pattern |
Negates previous patterns |
#comment |
Ignored line |
\* matches literal *Pattern compilation and matching is highly optimized:
OnceCellMatchOptions| Field | Type | Default | Description |
|---|---|---|---|
case_sensitive |
bool |
Platform | Match case-sensitively |
require_literal_separator |
bool |
true |
* doesn't match / |
require_literal_leading_dot |
bool |
true |
* doesn't match .hidden |
IgnoreOptions| Field | Type | Default | Description |
|---|---|---|---|
hidden |
bool |
true |
Ignore hidden files (.file) |
parents |
bool |
true |
Check parent .gitignore files |
git_global |
bool |
false |
Use Git global ignore |
git_exclude |
bool |
false |
Use .git/info/exclude |
All pattern operations return Result<T, PatternError>:
pub enum PatternError {
InvalidGlob(String), // Malformed glob syntax
InvalidRegex(String), // Malformed regex pattern
IoError(io::Error), // File read errors
EmptyPatternSet, // No patterns provided
}
scribe-patterns is used throughout Scribe:
--include and --exclude flagsscribe-scanner: Repository scanning and filteringscribe-selection: File selection using patternsscribe-core: Shared types and configuration