Skip to main content

IndexedFirstMatch

Struct IndexedFirstMatch 

Source
pub struct IndexedFirstMatch<T: ?Sized, Decision> { /* private fields */ }
Expand description

Ordered decisions indexed by caller-declared necessary string keys.

The key projection runs once for each call to DecisionSpecification::decide. Evaluation considers only the matching key bucket and unkeyed rules, merging both groups in insertion order and stopping at the first match. Bucket lookup uses borrowed str access and index evaluation adds no allocation.

A keyed rule’s key is a necessary condition: its specification must never match a candidate whose projected key differs from the registered key. This cannot be checked for arbitrary specifications. Rules without such a sound key must be registered with push_unkeyed.

The stored specifications require Send + Sync, so a completed index can be shared by worker threads whenever its decisions are also Sync.

use specification_core::{DecisionSpecification, IndexedFirstMatch};

struct File<'a> { name: &'a str, executable: bool }
let mut routes = IndexedFirstMatch::new(|file: &File<'_>| file.name);
routes.push_keyed(
    "Cargo.toml",
    |file: &File<'_>| file.name == "Cargo.toml" && file.executable,
    "manifest",
);
routes.push_unkeyed(|file: &File<'_>| file.name.ends_with(".lock"), "lockfile");

let manifest = File { name: "Cargo.toml", executable: true };
let lock = File { name: "Cargo.lock", executable: false };
assert_eq!(routes.decide(&manifest), Some(&"manifest"));
assert_eq!(routes.decide(&lock), Some(&"lockfile"));
assert!(routes.may_match("Cargo.lock"));

Implementations§

Source§

impl<T: ?Sized, Decision> IndexedFirstMatch<T, Decision>

Source

pub fn new<Projection>(key_of: Projection) -> Self
where Projection: for<'candidate> Fn(&'candidate T) -> &'candidate str + Send + Sync + 'static,

Creates an empty index using a borrowed string-key projection.

The projection must be stable for the candidate during one evaluation.

Source

pub fn push_keyed<Concrete>( &mut self, key: impl Into<String>, specification: Concrete, decision: Decision, )
where Concrete: Specification<T> + Send + Sync + 'static,

Adds a rule to the bucket for its necessary key.

The specification must return true only for candidates whose projected key equals key. Duplicate keys are supported and retain insertion order.

Source

pub fn push_unkeyed<Concrete>( &mut self, specification: Concrete, decision: Decision, )
where Concrete: Specification<T> + Send + Sync + 'static,

Adds a rule considered for every candidate, in insertion order.

Source

pub fn may_match(&self, key: &str) -> bool

Returns whether a candidate with key could match.

This is conservative: if any unkeyed rules are registered, this returns true even when the keyed bucket is absent. It does not evaluate rules.

Trait Implementations§

Source§

impl<T: ?Sized, Decision> DecisionSpecification<T> for IndexedFirstMatch<T, Decision>

Source§

type Decision = Decision

The decision selected by this rule.
Source§

fn decide(&self, candidate: &T) -> Option<&Decision>

Returns the selected decision, or None when no rule matches.

Auto Trait Implementations§

§

impl<T, Decision> !RefUnwindSafe for IndexedFirstMatch<T, Decision>

§

impl<T, Decision> !UnwindSafe for IndexedFirstMatch<T, Decision>

§

impl<T, Decision> Freeze for IndexedFirstMatch<T, Decision>
where T: ?Sized,

§

impl<T, Decision> Send for IndexedFirstMatch<T, Decision>
where Decision: Send, T: ?Sized,

§

impl<T, Decision> Sync for IndexedFirstMatch<T, Decision>
where Decision: Sync, T: ?Sized,

§

impl<T, Decision> Unpin for IndexedFirstMatch<T, Decision>
where Decision: Unpin, T: ?Sized,

§

impl<T, Decision> UnsafeUnpin for IndexedFirstMatch<T, Decision>
where T: ?Sized,

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> 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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.