pub struct ChimeraExpressionSet<'a> { /* private fields */ }
Available on crate features compiler and chimera only.
Expand description

Collection of regular expressions.

This is the analogue to super::ExpressionSet for ChimeraExpression instances.

This struct provides an immutable (returning Self) builder interface to attach additional configuration to the initial set of patterns constructed with Self::from_exprs().

Implementations§

source§

impl<'a> ChimeraExpressionSet<'a>

source

pub fn from_exprs( exprs: impl IntoIterator<Item = &'a ChimeraExpression> ) -> Self

Construct a pattern set from references to parsed expressions.

The length of this initial exprs argument is returned by Self::len(), and all subsequent configuration methods are checked to provide iterators of the same length:

 use vectorscan::expression::chimera::*;

 let a: ChimeraExpression = "a+".parse().unwrap();
 // Fails due to argument length mismatch:
 ChimeraExpressionSet::from_exprs([&a])
   .with_flags([]);
source

pub fn with_flags(self, flags: impl IntoIterator<Item = ChimeraFlags>) -> Self

Provide flags which modify the behavior of each expression.

The length of flags is checked to be the same as Self::len().

If this builder method is not used, ChimeraFlags::default() will be assigned to all patterns.

 use vectorscan::{expression::chimera::*, flags::chimera::*, matchers::chimera::*};

 // Create two expressions to demonstrate separate flags for each pattern:
 let a: ChimeraExpression = "a+[^a]".parse()?;
 let b: ChimeraExpression = "b+[^b]".parse()?;

 // Get the start of match for one pattern, but not the other:
 let db = ChimeraExpressionSet::from_exprs([&a, &b])
   .with_flags([ChimeraFlags::default(), ChimeraFlags::SINGLEMATCH])
   .compile(ChimeraMode::NOGROUPS)?;

 let mut scratch = db.allocate_scratch()?;

 let mut matches: Vec<&str> = Vec::new();
 scratch.scan_sync(&db, "aardvark imbibbe".into(), |m| {
   matches.push(unsafe { m.source.as_str() });
   ChimeraMatchResult::Continue
 }, |_| ChimeraMatchResult::Continue)?;
 // SINGLEMATCH is preserved for only one pattern:
 assert_eq!(&matches, &["aar", "ar", "bi"]);
source

pub fn with_ids(self, ids: impl IntoIterator<Item = ExprId>) -> Self

Assign an ID number to each pattern.

The length of ids is checked to be the same as Self::len(). Multiple patterns can be assigned the same ID.

If this builder method is not used, vectorscan will assign them all the ID number 0:

 use vectorscan::{sources::*, expression::{*, chimera::*}, flags::chimera::*, state::chimera::*, matchers::{*, chimera::*}};

 // Create two expressions to demonstrate multiple pattern IDs.
 let a: ChimeraExpression = "a+[^a]".parse()?;
 let b: ChimeraExpression = "b+[^b]".parse()?;

 // Create one db with ID numbers, and one without.
 let set1 = ChimeraExpressionSet::from_exprs([&a, &b]).compile(ChimeraMode::NOGROUPS)?;
 let set2 = ChimeraExpressionSet::from_exprs([&a, &b])
   .with_ids([ExprId(300), ExprId(12)])
   .compile(ChimeraMode::NOGROUPS)?;

 let mut scratch = ChimeraScratch::blank();
 scratch.setup_for_db(&set1)?;
 scratch.setup_for_db(&set2)?;

 let msg: ByteSlice = "aardvark imbibbe".into();

 // The first db doesn't differentiate matches by ID number:
 let mut matches1: Vec<ExpressionIndex> = Vec::new();
 scratch.scan_sync(&set1, msg, |m| {
   matches1.push(m.id);
   ChimeraMatchResult::Continue
 }, |_| ChimeraMatchResult::Continue)?;
 assert_eq!(
   &matches1,
   &[ExpressionIndex(0), ExpressionIndex(0), ExpressionIndex(0), ExpressionIndex(0)],
 );

 // The second db returns corresponding ExpressionIndex instances:
 let mut matches2: Vec<ExpressionIndex> = Vec::new();
 scratch.scan_sync(&set2, msg, |m| {
   matches2.push(m.id);
   ChimeraMatchResult::Continue
 }, |_| ChimeraMatchResult::Continue)?;
 assert_eq!(
   &matches2,
   &[ExpressionIndex(300), ExpressionIndex(300), ExpressionIndex(12), ExpressionIndex(12)],
 );
source

pub fn with_limits(self, limits: ChimeraMatchLimits) -> Self

Assign extended PCRE configuration to the entire pattern set.

This is the only entry point to configuring PCRE match limits (i.e. the single-pattern compiler does not support match limits).

 use vectorscan::{sources::*, expression::chimera::*, flags::chimera::*, state::chimera::*, matchers::chimera::*, error::chimera::*};

 // Create one db with backtracking match limits, and one without.
 let a: ChimeraExpression = r"(asdf?)hey\1".parse()?;
 let set1 = ChimeraExpressionSet::from_exprs([&a]).compile(ChimeraMode::GROUPS)?;
 let set2 = ChimeraExpressionSet::from_exprs([&a])
   .with_limits(ChimeraMatchLimits { match_limit: 1, match_limit_recursion: 1 })
   .compile(ChimeraMode::GROUPS)?;

 let mut scratch = ChimeraScratch::blank();
 scratch.setup_for_db(&set1)?;
 scratch.setup_for_db(&set2)?;

 let msg: ByteSlice = "asdfheyasdf".into();

 // The first db doesn't stop the matching engine:
 let mut matches1: Vec<&str> = Vec::new();
 scratch.scan_sync(&set1, msg, |m| {
   matches1.push(unsafe { m.captures.unwrap()[1].unwrap().as_str() });
   ChimeraMatchResult::Continue
 }, |_| ChimeraMatchResult::Terminate)?;
 assert_eq!(&matches1, &["asdf"]);

 // The second db imposes a match limit, which triggers the second callback to return
 // `ChimeraMatchResult::Terminate`.
 let mut matches2: Vec<ChimeraMatchError> = Vec::new();
 let result = scratch.scan_sync(
   &set2,
   msg,
   |_| unreachable!(),
   |e| {
     matches2.push(e);
     ChimeraMatchResult::Terminate
   },
 );
 assert!(matches![result, Err(ChimeraRuntimeError::ScanTerminated)]);
 assert_eq!(matches2.len(), 1);
 assert_eq!(matches2[0].error_type, ChimeraMatchErrorType::MatchLimit);
source

pub fn compile( self, mode: ChimeraMode ) -> Result<ChimeraDb, ChimeraCompileError>

Call ChimeraDb::compile_multi() with None for the platform.

source

pub fn len(&self) -> usize

The number of patterns in this set.

source

pub fn is_empty(&self) -> bool

Whether this set contains any patterns.

Trait Implementations§

source§

impl<'a> Clone for ChimeraExpressionSet<'a>

source§

fn clone(&self) -> ChimeraExpressionSet<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'a> Debug for ChimeraExpressionSet<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

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>,

§

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.