use proc_macro2::{LexError, TokenStream};
use thiserror::Error;
mod compile;
#[cfg(feature = "dynamic")]
mod dynamic;
mod parse;
mod regex;
#[cfg(feature = "rust-code-emitting")]
mod emit;
#[cfg(feature = "dot")]
mod dot;
pub use compile::{Automaton, MatchState};
pub use regex::Regex;
pub trait RegexMatcher<A>: Clone {
fn step(&mut self, inp: A);
fn step_many(&mut self, inp: impl IntoIterator<Item = A>) {
for i in inp {
self.step(i);
}
}
fn step_unless_empty(&mut self, inp: impl IntoIterator<Item = A>) {
for i in inp {
self.step(i);
if self.is_empty() {
return;
}
}
}
fn accepts(&self, iter: impl IntoIterator<Item = A>) -> bool {
let mut this = self.clone();
this.step_unless_empty(iter);
this.is_accepting()
}
fn accepts_prefix(&self, iter: impl IntoIterator<Item = A>) -> bool {
let mut this = self.clone();
this.step_unless_empty(iter);
!this.is_empty()
}
fn is_final(&self) -> bool;
fn is_accepting(&self) -> bool;
fn is_empty(&self) -> bool {
self.is_final() && !self.is_accepting()
}
}
#[derive(Error, Debug)]
pub enum ParseError {
#[error("lex error: {0}")]
Lex(#[from] LexError),
#[error("parse error: {0}")]
Parse(#[from] syn::Error),
}
pub fn parse_regex(input: impl AsRef<str>) -> Result<Regex, ParseError> {
let stream: TokenStream = input.as_ref().parse()?;
Ok(parse_regex_token_stream(stream)?)
}
pub fn parse_regex_token_stream(input: TokenStream) -> syn::Result<Regex> {
syn::parse2(input)
}