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#[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}