Skip to main content

Crate matcher_rs

Crate matcher_rs 

Source
Expand description

High-performance multi-pattern text matcher with logical operators and transformation pipelines.

matcher_rs is designed for rule matching tasks where plain substring search is too rigid. A rule can combine multiple sub-patterns, veto on other sub-patterns, and match against raw text, transformed text, or both.

The crate is built around three ideas:

  • Logical operators — Rules can require co-occurrence of sub-patterns (&) or veto a match when a sub-pattern is present (~).
  • Transformation pipelines — Input can be matched after Traditional→Simplified CJK variant normalization (ProcessType::VariantNorm), deletion of configured codepoints (ProcessType::Delete), replacement-table normalization (ProcessType::Normalize), and CJK romanization (ProcessType::Romanize / ProcessType::RomanizeChar).
  • Two-pass evaluation — Construction deduplicates emitted patterns and partitions them into ASCII and charwise matcher engines. Search walks the needed transform tree once, scans each produced text variant, then evaluates only touched rules.

§Quick Start

use matcher_rs::{ProcessType, SimpleMatcherBuilder};

let matcher = SimpleMatcherBuilder::new()
    .add_word(ProcessType::None, 1, "hello")
    // Matches after converting Traditional Chinese and removing noise chars
    .add_word(ProcessType::VariantNormDeleteNormalize, 2, "你好")
    // Both sub-patterns must appear in the text
    .add_word(ProcessType::None, 3, "apple&pie")
    // "banana" matches only when "peel" is absent
    .add_word(ProcessType::None, 4, "banana~peel")
    .build()
    .unwrap();

assert!(matcher.is_match("hello world"));
assert!(matcher.is_match("apple and pie"));
assert!(!matcher.is_match("banana peel")); // vetoed by ~peel

let results = matcher.process("hello world");
assert_eq!(results[0].word_id, 1);

Composite ProcessType values can also include ProcessType::None to match against both the raw text and a transformed variant. For example, a rule with ProcessType::None | ProcessType::Romanize can satisfy one sub-pattern directly from the input and another via CJK romanization during the same search.

§Safety

This crate uses unsafe in three categories:

§Thread-local state via #[thread_local] + UnsafeCell

StaticLocation
SIMPLE_MATCH_STATEsimple_matcher/state.rs

This uses #[thread_local] + UnsafeCell instead of the thread_local! macro to avoid per-access closure overhead. Safety relies on two invariants: (1) #[thread_local] guarantees single-threaded access — no data races. (2) No public function is re-entrant: the borrow from UnsafeCell::get() is always dropped before any call that could re-enter the same state.

§Bounds-elided indexing

Hot loops use get_unchecked / get_unchecked_mut to avoid repeated bounds checks on indices that are structurally guaranteed in-bounds by construction (e.g. automaton values, rule indices). Every such site communicates the invariant to the optimizer via core::hint::assert_unchecked.

§Feature Flags

FlagDefaultEffect
perfonMeta-feature enabling dfa + simd_runtime_dispatch
dfavia perfEnables aho-corasick DFA mode in the places where this crate chooses it; other paths still use daachorse-backed matchers
simd_runtime_dispatchvia perfSelects the best available transform kernel at runtime (AVX2 on x86-64, NEON on ARM64, portable fallback elsewhere)
serdeoffEnables Serialize/Deserialize impls for ProcessType and Serialize for SimpleResult

§Terminology

TermMeaning
RuleA user-supplied pattern string, possibly with & (AND), ~ (NOT), | (OR) operators. Identified by a caller-chosen word_id.
SegmentOne sub-pattern within a rule, delimited by & or ~. A segment may contain |-separated alternatives.
PatternA deduplicated sub-pattern string stored in the AC automaton. Multiple rules may share the same pattern.
VariantOne transformed form of the input text (e.g., after VariantNorm, after Delete). Each variant gets a unique index.
GenerationA monotonic u16 counter enabling O(1) amortized state reset between scans. Wraps every ~65K scans.
Direct encodingBit-packing a single-entry pattern’s metadata into the automaton value, bypassing entry-table indirection. See simple_matcher::pattern.

For the full architectural walkthrough, see DESIGN.md.

Structs§

ProcessType
Bitflags controlling which text-transformation steps to apply before matching.
SimpleMatcher
Multi-pattern matcher with logical operators and text normalization.
SimpleMatcherBuilder
Builder for constructing a SimpleMatcher.
SimpleResult
A single match returned by SimpleMatcher::process or SimpleMatcher::process_into.

Enums§

MatcherError
Error returned when super::SimpleMatcher construction fails.

Functions§

reduce_text_process
Applies a composite ProcessType pipeline to text, recording every intermediate change.
reduce_text_process_emit
Like reduce_text_process, but merges replace-type steps in-place.
text_process
Applies a composite ProcessType pipeline to text and returns the final result.

Type Aliases§

SimpleTable
Raw table format accepted by SimpleMatcher::new.
SimpleTableSerde
Serde-friendly table format that stores rule strings as Cow<str>.