neure/re/regex/
not.rs

1use crate::ctx::Context;
2use crate::ctx::CtxGuard;
3use crate::ctx::Match;
4use crate::ctx::Ret;
5use crate::ctx::Span;
6use crate::err::Error;
7use crate::re::def_not;
8use crate::re::trace;
9use crate::re::Ctor;
10use crate::re::Extract;
11use crate::re::Handler;
12use crate::re::Regex;
13
14/// Reverse the result, return zero length [`Span`] if match failed.
15///
16/// # Regex
17///
18/// Return zero length [`Span`] if `T` match failed.
19#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
20pub struct RegexNot<T> {
21    val: T,
22}
23
24impl<T> RegexNot<T> {
25    pub fn new(val: T) -> Self {
26        Self { val }
27    }
28}
29
30def_not!(RegexNot<T>);
31
32impl<'a, C, O, T, H, A> Ctor<'a, C, O, O, H, A> for RegexNot<T>
33where
34    T: Regex<C, Ret = Span>,
35    C: Context<'a> + Match<C>,
36    H: Handler<A, Out = O, Error = Error>,
37    A: Extract<'a, C, Span, Out<'a> = A, Error = Error>,
38{
39    #[inline(always)]
40    fn construct(&self, ctx: &mut C, func: &mut H) -> Result<O, Error> {
41        let ret = ctx.try_mat(self)?;
42
43        func.invoke(A::extract(ctx, &ret)?)
44    }
45}
46
47impl<'a, C, T> Regex<C> for RegexNot<T>
48where
49    T: Regex<C>,
50    <T as Regex<C>>::Ret: Ret,
51    C: Context<'a> + Match<C>,
52{
53    type Ret = T::Ret;
54
55    #[inline(always)]
56    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, crate::err::Error> {
57        let mut g = CtxGuard::new(ctx);
58        let mut ret = Err(Error::Not);
59        let beg = g.beg();
60        let r = trace!("not", beg, g.try_mat(&self.val));
61
62        if r.is_err() {
63            ret = Ok(<T::Ret as Ret>::from_ctx(g.ctx(), (0, 0)));
64        }
65        trace!("not", beg => g.reset().end(), ret)
66    }
67}