Struct ScratchStreamSinkChannel

Source
pub struct ScratchStreamSinkChannel<'code> {
    pub live: Box<dyn Handle<R = LiveStream> + Send>,
    pub hf: Box<dyn FnMut(StreamMatch) -> MatchResult + Send + 'code>,
    pub scratch: Box<dyn Handle<R = Scratch> + Send>,
    pub rx: UnboundedReceiver<StreamMatch>,
}
Available on crate features stream and async only.
Expand description

An async version of super::ScratchStreamSink.

By holding handles to Self::live and Self::scratch, the stream scanning API can be made quite fluent, without as many parameters per call:

 #[cfg(feature = "compiler")]
 fn main() -> Result<(), vectorscan::error::VectorscanError> { tokio_test::block_on(async {
   use vectorscan::{expression::*, flags::*, stream::channel::*, matchers::*};
   use futures_util::StreamExt;
   use std::ops::Range;

   let expr: Expression = "a+".parse()?;
   let db = expr.compile(Flags::SOM_LEFTMOST, Mode::STREAM | Mode::SOM_HORIZON_LARGE)?;
   let scratch = db.allocate_scratch()?;
   let live = db.allocate_stream()?;

   let mut match_fn = |_: &_| MatchResult::Continue;
   let mut sink = ScratchStreamSinkChannel::new(live, &mut match_fn, scratch);

   sink.scan("aardvark".into()).await?;
   sink.flush_eod().await?;

   let matches: Vec<Range<usize>> = sink.collect_matches()
     .map(|m| m.range.into())
     .collect()
     .await;
   assert_eq!(&matches, &[0..1, 0..2, 5..6]);
   Ok(())
 })}

Fields§

§live: Box<dyn Handle<R = LiveStream> + Send>

Cloneable handle to a stateful stream.

§hf: Box<dyn FnMut(StreamMatch) -> MatchResult + Send + 'code>

A “handler function” synthesized by Self::new() which closes over an mpsc::UnboundedSender.

§scratch: Box<dyn Handle<R = Scratch> + Send>

Cloneable handle to a scratch space initialized for the same db as Self::live.

§rx: UnboundedReceiver<StreamMatch>

The other half of the sender/receiver pair created by Self::new().

Implementations§

Source§

impl<'code> ScratchStreamSinkChannel<'code>

Source

pub fn new( live: impl Handle<R = LiveStream> + Send, hf: &'code mut (dyn FnMut(&StreamMatch) -> MatchResult + Send + 'code), scratch: impl Handle<R = Scratch> + Send, ) -> Self

Generate an mpsc::unbounded_channel() and a wrapper over the provided handler function hf that sends match objects into the channel as messages.

Source

pub async fn scan<'data>( &mut self, data: ByteSlice<'data>, ) -> Result<(), ScanError>

Write a single contiguous string into the automaton.

 #[cfg(feature = "compiler")]
 fn main() -> Result<(), vectorscan::error::VectorscanError> { tokio_test::block_on(async {
   use vectorscan::{expression::*, flags::*, stream::channel::*, matchers::*};
   use futures_util::StreamExt;
   use std::ops::Range;

   let expr: Expression = "a+".parse()?;
   let db = expr.compile(Flags::SOM_LEFTMOST, Mode::STREAM | Mode::SOM_HORIZON_LARGE)?;
   let scratch = db.allocate_scratch()?;
   let live = db.allocate_stream()?;

   let mut match_fn = |_: &_| MatchResult::Continue;
   let mut sink = ScratchStreamSinkChannel::new(live, &mut match_fn, scratch);

   sink.scan("aardvarka".into()).await?;
   sink.scan("a".into()).await?;
   sink.flush_eod().await?;

   let matches: Vec<Range<usize>> = sink.collect_matches()
     .map(|m| m.range.into())
     .collect()
     .await;
   // 8..10 crossed our non-contiguous inputs!
   assert_eq!(&matches, &[0..1, 0..2, 5..6, 8..9, 8..10]);
   Ok(())
 })}
Source

pub async fn scan_vectored<'data>( &mut self, data: VectoredByteSlices<'data, 'data>, ) -> Result<(), ScanError>

Available on crate feature vectored only.

Write vectored string data into the automaton.

 #[cfg(feature = "compiler")]
 fn main() -> Result<(), vectorscan::error::VectorscanError> { tokio_test::block_on(async {
   use vectorscan::{expression::*, flags::*, stream::channel::*, matchers::*, sources::*};
   use futures_util::StreamExt;
   use std::ops::Range;

   let expr: Expression = "a+".parse()?;
   let db = expr.compile(Flags::SOM_LEFTMOST, Mode::STREAM | Mode::SOM_HORIZON_LARGE)?;
   let scratch = db.allocate_scratch()?;
   let live = db.allocate_stream()?;

   let mut match_fn = |_: &_| MatchResult::Continue;
   let mut sink = ScratchStreamSinkChannel::new(live, &mut match_fn, scratch);

   let input: [ByteSlice; 2] = [
     "aardvarka".into(),
     "a".into(),
   ];

   sink.scan_vectored(input.as_ref().into()).await?;
   sink.flush_eod().await?;

   let matches: Vec<Range<usize>> = sink.collect_matches()
     .map(|m| m.range.into())
     .collect()
     .await;
   // 8..10 crossed our non-contiguous inputs!
   assert_eq!(&matches, &[0..1, 0..2, 5..6, 8..9, 8..10]);
   Ok(())
 })}
Source

pub async fn flush_eod(&mut self) -> Result<(), ScanError>

Trigger any match callbacks that require matching against the end of data (EOD).

Expression::info() returns a MatchAtEndBehavior can be used to determine whether this check is necessary. But it typically makes sense to execute it exactly once at the end of every stream instead of trying to optimize this away.

Source

pub fn collect_matches(self) -> impl Stream<Item = StreamMatch>

Call mpsc::UnboundedReceiver::close() on Self::rx then convert it into an async iterable stream.

Source

pub fn reset(&mut self) -> Result<(), VectorscanRuntimeError>

Reach into Self::live and call LiveStream::reset().

Auto Trait Implementations§

§

impl<'code> Freeze for ScratchStreamSinkChannel<'code>

§

impl<'code> !RefUnwindSafe for ScratchStreamSinkChannel<'code>

§

impl<'code> Send for ScratchStreamSinkChannel<'code>

§

impl<'code> !Sync for ScratchStreamSinkChannel<'code>

§

impl<'code> Unpin for ScratchStreamSinkChannel<'code>

§

impl<'code> !UnwindSafe for ScratchStreamSinkChannel<'code>

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.