pub struct Matcher { /* private fields */ }Expand description
Matcher.
Matchers provide efficient matching of identifiers against an arbitrary set
of selectors in linear time, implemented through the use of the globset
crate, which compiles globs into deterministic finite automata (DFA). Each
[Component] of the matcher receives its own distinct GlobSet.
While components are matched one after another, all registered identifiers
in a [Component] are matched in linear time, i.e., O(n), where n is the
length of the component value. The Matches returned by each component
are intersected, leaving only selectors that match all components. There
are theoretical limits on the number of selectors that can be added to a
[Component], so it can be necessary to split across multiple matchers if
the number of selectors is high, i.e., 10,000 or more.
§Examples
use zrx_id::{Id, Matcher};
// Create matcher builder and add selector
let mut builder = Matcher::builder();
builder.add(&"zrs:::::**/*.md:")?;
// Create matcher from builder
let matcher = builder.build()?;
// Create identifier and match selector
let id: Id = "zri:file:::docs:index.md:".parse()?;
assert!(matcher.is_match(&id)?);Implementations§
Source§impl Matcher
impl Matcher
Sourcepub fn is_match<T>(&self, id: &T) -> Result<bool>where
T: TryToId,
pub fn is_match<T>(&self, id: &T) -> Result<bool>where
T: TryToId,
Returns whether the given identifier matches any selector.
Components are compared in descending variability and their likelihood
for mismatch, starting with the location. This approach effectively
tries to short-circuits the comparison. Note that empty components are
considered wildcards, so they will always match.
§Errors
Returns Error::Id if the identifier is invalid.
§Examples
use zrx_id::{Id, Matcher};
// Create matcher builder and add selector
let mut builder = Matcher::builder();
builder.add(&"zrs:::::**/*.md:")?;
// Create matcher from builder
let matcher = builder.build()?;
// Create identifier and match selector
let id: Id = "zri:file:::docs:index.md:".parse()?;
assert!(matcher.is_match(&id)?);Sourcepub fn matches<T>(&self, id: &T) -> Result<Matches>where
T: TryToId,
pub fn matches<T>(&self, id: &T) -> Result<Matches>where
T: TryToId,
Returns the indices of selectors that match the identifier.
This method compares each component of the identifier against the
corresponding component of a selector using the compiled globs, and
returns the indices of the matching selectors in the order they were
added to the Matcher.
Components are compared in descending variability and their likelihood
for mismatch, starting with the location. This approach effectively
tries to short-circuit the comparison. Note that empty components are
considered wildcards, so they will always match.
§Errors
Returns Error::Id if the identifier is invalid.
§Examples
use zrx_id::{Id, Matcher, Matches};
// Create matcher builder and add selector
let mut builder = Matcher::builder();
builder.add(&"zrs:::::**/*.md:")?;
// Create matcher from builder
let matcher = builder.build()?;
// Create identifier and obtain matched selectors
let id: Id = "zri:file:::docs:index.md:".parse()?;
assert_eq!(matcher.matches(&id)?, Matches::from_iter([0]));Trait Implementations§
Source§impl FromStr for Matcher
impl FromStr for Matcher
Source§fn from_str(value: &str) -> Result<Self>
fn from_str(value: &str) -> Result<Self>
Attempts to create a matcher from a string.
The string must adhere to the following format and include exactly six
: separators, even if some components are empty. All components are
optional, which means they can be left empty, which is equivalent to
setting them to a ** wildcard.
zrs:<provider>:<resource>:<variant>:<context>:<location>:<fragment>§Errors
Returns Error::Id if the given string can’t be parsed into a valid
selector, from which the matcher is then constructed.
§Examples
use zrx_id::Matcher;
// Create matcher from string
let matcher: Matcher = "zrs:::::**/*.md:".parse()?;