use crate::ctor::Ctor;
use crate::ctor::Handler;
use crate::ctx::Match;
use crate::err::Error;
use crate::regex::Regex;
use crate::regex::impl_not_for_regex;
use crate::span::Span;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Assert<T> {
pat: T,
value: bool,
}
impl<T> Assert<T> {
pub const fn new(pat: T, value: bool) -> Self {
Self { pat, value }
}
pub const fn pat(&self) -> &T {
&self.pat
}
pub const fn value(&self) -> bool {
self.value
}
pub const fn pat_mut(&mut self) -> &mut T {
&mut self.pat
}
pub fn set_pat(&mut self, pat: T) -> &mut Self {
self.pat = pat;
self
}
pub fn set_value(&mut self, value: bool) -> &mut Self {
self.value = value;
self
}
pub fn with_value(mut self, value: bool) -> Self {
self.value = value;
self
}
}
impl_not_for_regex!(Assert<T>);
impl<'a, C, O, T, H> Ctor<C, O, H> for Assert<T>
where
T: Regex<C>,
C: Match<'a>,
H: Handler<C, Out = O>,
{
#[inline(always)]
fn construct(&self, ctx: &mut C, func: &mut H) -> Result<O, Error> {
let ret = ctx.try_mat(self)?;
func.invoke(ctx, &ret).map_err(Into::into)
}
}
impl<'a, C, T> Regex<C> for Assert<T>
where
T: Regex<C>,
C: Match<'a>,
{
#[inline(always)]
fn try_parse(&self, ctx: &mut C) -> Result<Span, crate::err::Error> {
let offset = ctx.offset();
crate::debug_regex_beg!("Assert", offset);
let ret = if ctx.try_mat(&self.pat).is_ok() == self.value {
Ok(Span::new(offset, 0))
} else if self.value {
Err(Error::AssertTrue)
} else {
Err(Error::AssertFalse)
};
ctx.set_offset(offset); crate::debug_regex_reval!("Assert", ret)
}
}
pub const fn assert<T>(pat: T, value: bool) -> Assert<T> {
Assert::new(pat, value)
}
pub const fn not<T>(pat: T) -> crate::regex::Assert<T> {
crate::regex::Assert::new(pat, false)
}
pub const fn peek<T>(pat: T) -> crate::regex::Assert<T> {
crate::regex::Assert::new(pat, true)
}