neure/
re.rs

1mod extract;
2mod into;
3mod null;
4mod rec;
5mod wrap;
6
7pub mod ctor;
8pub mod regex;
9
10use std::cell::Cell;
11use std::cell::RefCell;
12use std::rc::Rc;
13use std::sync::Arc;
14use std::sync::Mutex;
15
16pub use self::ctor::branch;
17pub use self::ctor::Array;
18pub use self::ctor::ConstructOp;
19pub use self::ctor::Ctor;
20pub use self::ctor::DynamicArcCtor;
21pub use self::ctor::DynamicBoxedCtor;
22pub use self::ctor::DynamicBoxedCtorSync;
23pub use self::ctor::DynamicCreateCtorThen;
24pub use self::ctor::DynamicCreateCtorThenHelper;
25pub use self::ctor::DynamicRcCtor;
26pub use self::ctor::PairArray;
27pub use self::ctor::PairSlice;
28pub use self::ctor::PairVector;
29pub use self::ctor::Slice;
30pub use self::ctor::Vector;
31pub use self::extract::Extract;
32pub use self::extract::Handler;
33pub use self::extract::Pass;
34pub use self::into::ConstructIntoOp;
35pub use self::into::RegexIntoOp;
36pub use self::null::NullRegex;
37pub use self::rec::rec_parser;
38pub use self::rec::rec_parser_sync;
39pub use self::rec::rec_parser_with;
40pub use self::rec::rec_parser_with_sync;
41pub use self::rec::RecParser;
42pub use self::rec::RecParserSync;
43pub use self::rec::RecursiveCtor;
44pub use self::rec::RecursiveCtorSync;
45pub use self::rec::RecursiveCtorWith;
46pub use self::rec::RecursiveCtorWithSync;
47pub use self::rec::RecursiveParser;
48pub use self::rec::RecursiveParserSync;
49pub use self::regex::AnchorEnd;
50pub use self::regex::AnchorStart;
51pub use self::regex::BoxedRegex;
52pub use self::regex::Consume;
53pub use self::regex::ConsumeAll;
54pub use self::regex::DynamicArcRegex;
55pub use self::regex::DynamicBoxedRegex;
56pub use self::regex::DynamicCreateRegexThenHelper;
57pub use self::regex::DynamicRcRegex;
58pub use self::regex::LitSlice;
59pub use self::regex::LitString;
60pub use self::regex::RegexNot;
61pub use self::wrap::Wrapped;
62pub use self::wrap::WrappedTy;
63
64use crate::ctx::Context;
65use crate::ctx::Match;
66use crate::ctx::Span;
67use crate::err::Error;
68use crate::neu::Condition;
69use crate::neu::Neu;
70use crate::neu::Neu2Re;
71use crate::neu::NeureOne;
72use crate::neu::NeureOneMore;
73use crate::neu::NeureZeroMore;
74use crate::neu::NeureZeroOne;
75use crate::neu::NullCond;
76
77pub trait Regex<C> {
78    type Ret;
79
80    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error>;
81
82    fn parse(&self, ctx: &mut C) -> bool {
83        self.try_parse(ctx).is_ok()
84    }
85}
86
87impl<C, F, R> Regex<C> for F
88where
89    F: Fn(&mut C) -> Result<R, Error>,
90{
91    type Ret = R;
92
93    #[inline]
94    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
95        (self)(ctx)
96    }
97}
98
99impl<'a, C> Regex<C> for &str
100where
101    C: Context<'a, Orig = str> + Match<C>,
102{
103    type Ret = Span;
104
105    #[inline(always)]
106    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
107        let pattern = crate::re::string(self);
108        pattern.try_parse(ctx)
109    }
110}
111
112impl<'a, C> Regex<C> for String
113where
114    C: Context<'a, Orig = str> + Match<C>,
115{
116    type Ret = Span;
117
118    #[inline(always)]
119    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
120        let pattern = crate::re::string(self.as_str());
121        pattern.try_parse(ctx)
122    }
123}
124
125impl<'a, C> Regex<C> for &String
126where
127    C: Context<'a, Orig = str> + Match<C>,
128{
129    type Ret = Span;
130
131    #[inline(always)]
132    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
133        let pattern = crate::re::string(self.as_str());
134        pattern.try_parse(ctx)
135    }
136}
137
138impl<'a, C> Regex<C> for &[u8]
139where
140    C: Context<'a, Orig = [u8]> + Match<C>,
141{
142    type Ret = Span;
143
144    #[inline(always)]
145    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
146        let pattern = crate::re::lit_slice(self);
147        pattern.try_parse(ctx)
148    }
149}
150
151impl<'a, const N: usize, C> Regex<C> for &[u8; N]
152where
153    C: Context<'a, Orig = [u8]> + Match<C>,
154{
155    type Ret = Span;
156
157    #[inline(always)]
158    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
159        let pattern = crate::re::lit_slice(self.as_slice());
160        pattern.try_parse(ctx)
161    }
162}
163
164impl<'a, const N: usize, C> Regex<C> for [u8; N]
165where
166    C: Context<'a, Orig = [u8]> + Match<C>,
167{
168    type Ret = Span;
169
170    #[inline(always)]
171    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
172        let pattern = crate::re::lit_slice(self.as_slice());
173        pattern.try_parse(ctx)
174    }
175}
176
177impl<'a, C> Regex<C> for Vec<u8>
178where
179    C: Context<'a, Orig = [u8]> + Match<C>,
180{
181    type Ret = Span;
182
183    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
184        Regex::try_parse(&self.as_slice(), ctx)
185    }
186}
187
188impl<'a, C> Regex<C> for &Vec<u8>
189where
190    C: Context<'a, Orig = [u8]> + Match<C>,
191{
192    type Ret = Span;
193
194    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
195        Regex::try_parse(&self.as_slice(), ctx)
196    }
197}
198
199impl<'a, P, C> Regex<C> for Option<P>
200where
201    P: Regex<C>,
202    C: Context<'a> + Match<C>,
203{
204    type Ret = P::Ret;
205
206    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
207        self.as_ref().ok_or(Error::Option)?.try_parse(ctx)
208    }
209}
210
211impl<'a, P, C> Regex<C> for RefCell<P>
212where
213    P: Regex<C>,
214    C: Context<'a> + Match<C>,
215{
216    type Ret = P::Ret;
217
218    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
219        (*self.borrow()).try_parse(ctx)
220    }
221}
222
223impl<'a, P, C> Regex<C> for Cell<P>
224where
225    P: Regex<C> + Copy,
226    C: Context<'a> + Match<C>,
227{
228    type Ret = P::Ret;
229
230    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
231        self.get().try_parse(ctx)
232    }
233}
234
235impl<'a, P, C> Regex<C> for Mutex<P>
236where
237    P: Regex<C>,
238    C: Context<'a> + Match<C>,
239{
240    type Ret = P::Ret;
241
242    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
243        let ret = self.lock().map_err(|_| Error::LockMutex)?;
244        (*ret).try_parse(ctx)
245    }
246}
247
248impl<'a, P, C> Regex<C> for Arc<P>
249where
250    P: Regex<C>,
251    C: Context<'a> + Match<C>,
252{
253    type Ret = P::Ret;
254
255    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
256        self.as_ref().try_parse(ctx)
257    }
258}
259
260impl<'a, P, C> Regex<C> for Rc<P>
261where
262    P: Regex<C>,
263    C: Context<'a> + Match<C>,
264{
265    type Ret = P::Ret;
266
267    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
268        self.as_ref().try_parse(ctx)
269    }
270}
271
272impl<'a, Ret, C> Regex<C> for Box<dyn Regex<C, Ret = Ret>>
273where
274    C: Context<'a> + Match<C>,
275{
276    type Ret = Ret;
277
278    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
279        self.as_ref().try_parse(ctx)
280    }
281}
282
283impl<'a, Ret, C> Regex<C> for Arc<dyn Regex<C, Ret = Ret>>
284where
285    C: Context<'a> + Match<C>,
286{
287    type Ret = Ret;
288
289    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
290        self.as_ref().try_parse(ctx)
291    }
292}
293
294impl<'a, Ret, C> Regex<C> for Rc<dyn Regex<C, Ret = Ret>>
295where
296    C: Context<'a> + Match<C>,
297{
298    type Ret = Ret;
299
300    fn try_parse(&self, ctx: &mut C) -> Result<Self::Ret, Error> {
301        self.as_ref().try_parse(ctx)
302    }
303}
304
305///
306/// Match one item.
307///
308/// # Example
309///
310/// ```
311/// # use neure::prelude::*;
312/// #
313/// # fn main() -> color_eyre::Result<()> {
314/// #     color_eyre::install()?;
315///     let sign = re::one('+');
316///     let num = re::one_more('0'..='9');
317///     let mut ctx = CharsCtx::new("+2077");
318///
319///     assert_eq!(ctx.try_mat(&sign)?, Span::new(0, 1));
320///     assert_eq!(ctx.try_mat(&num)?, Span::new(1, 4));
321///
322///     let mut ctx = CharsCtx::new("2077");
323///
324///     assert!(ctx.try_mat(&sign).is_err());
325///     Ok(())
326/// # }
327/// ```
328pub fn one<'a, C, U>(unit: U) -> NeureOne<C, U, C::Item, NullCond>
329where
330    C: Context<'a>,
331    U: Neu<C::Item>,
332{
333    unit.repeat_one()
334}
335
336///
337/// Match zero or one item.
338///
339/// # Example
340///
341/// ```
342/// # use neure::prelude::*;
343/// #
344/// # fn main() -> color_eyre::Result<()> {
345/// #     color_eyre::install()?;
346///     let sign = re::zero_one('+');
347///     let num = re::one_more('0'..='9');
348///     let mut ctx = CharsCtx::new("+2077");
349///
350///     assert_eq!(ctx.try_mat(&sign)?, Span::new(0, 1));
351///     assert_eq!(ctx.try_mat(&num)?, Span::new(1, 4));
352///
353///     let mut ctx = CharsCtx::new("2077");
354///
355///     assert_eq!(ctx.try_mat(&sign)?, Span::new(0, 0));
356///     assert_eq!(ctx.try_mat(&num)?, Span::new(0, 4));
357///     Ok(())
358/// # }
359/// ```
360pub fn zero_one<'a, C, U>(unit: U) -> NeureZeroOne<C, U, C::Item, NullCond>
361where
362    C: Context<'a>,
363    U: Neu<C::Item>,
364{
365    unit.repeat_zero_one()
366}
367
368///
369/// Match at least zero item.
370///
371/// # Example
372///
373/// ```
374/// # use neure::prelude::*;
375/// #
376/// # fn main() -> color_eyre::Result<()> {
377/// #     color_eyre::install()?;
378///     let num = re::zero_more('0'..='9');
379///     let mut ctx = CharsCtx::new("2048mb");
380///
381///     assert_eq!(ctx.try_mat(&num)?, Span::new(0, 4));
382///
383///     let mut ctx = CharsCtx::new("rust2021");
384///
385///     assert_eq!(ctx.try_mat(&num)?, Span::new(0, 0));
386///     Ok(())
387/// # }
388/// ```
389///
390pub fn zero_more<'a, C, U>(unit: U) -> NeureZeroMore<C, U, C::Item, NullCond>
391where
392    C: Context<'a>,
393    U: Neu<C::Item>,
394{
395    unit.repeat_zero_more()
396}
397
398///
399/// Match at least one item.
400///
401/// # Example
402///
403/// ```
404/// # use neure::prelude::*;
405/// #
406/// # fn main() -> color_eyre::Result<()> {
407/// #     color_eyre::install()?;
408///     let num = re::one_more('0'..='9');
409///     let mut ctx = CharsCtx::new("2048mb");
410///
411///     assert_eq!(ctx.try_mat(&num)?, Span::new(0, 4));
412///
413///     let mut ctx = CharsCtx::new("rust2021");
414///
415///     assert!(ctx.try_mat(&num).is_err());
416///     Ok(())
417/// # }
418/// ```
419pub fn one_more<'a, C, N>(re: N) -> NeureOneMore<C, N, C::Item, NullCond>
420where
421    N: Neu<C::Item>,
422    C: Context<'a>,
423{
424    re.repeat_one_more()
425}
426
427///
428/// Match the given `Neu` M ..= N times.
429///
430/// # Example
431///
432/// ```
433/// # use neure::prelude::*;
434/// #
435/// # fn main() -> color_eyre::Result<()> {
436/// #     color_eyre::install()?;
437///     let website = re::count::<0, { usize::MAX }, _, _>(('a'..'{'));
438///     let mut ctx = CharsCtx::new("example.com");
439///
440///     assert_eq!(ctx.try_mat(&website)?, Span::new(0, 7));
441///     assert_eq!(ctx.orig_sub(0, 7)?, "example");
442///     Ok(())
443/// }
444/// ```
445///
446pub fn count<'a, const M: usize, const N: usize, C, U>(
447    unit: U,
448) -> crate::neu::NeureRepeat<M, N, C, U, NullCond>
449where
450    C: Context<'a>,
451    U: Neu<C::Item>,
452{
453    unit.repeat::<M, N>()
454}
455
456///
457/// Match the given `Neu` M ..= N times.
458///
459/// # Example
460///
461/// ```
462/// # use neure::prelude::*;
463/// #
464/// # fn main() -> color_eyre::Result<()> {
465/// #     color_eyre::install()?;
466///     let website = re::count_if::<0, { usize::MAX }, _, _, _>(
467///         ('a'..'{').or('.'),
468///         |ctx: &CharsCtx, pair: &(usize, char)| {
469///             Ok(pair.1 != '.'
470///                 || ctx
471///                     .orig()?
472///                     .get((pair.0 + 1)..)
473///                     .map(|v| v.find('.').is_some())
474///                     .unwrap_or(false))
475///         },
476///     );
477///     let mut ctx = CharsCtx::new("domain.example.com");
478///
479///     assert_eq!(ctx.try_mat(&website)?, Span::new(0, 14));
480///     assert_eq!(ctx.orig_sub(0, 14)?, "domain.example");
481///     Ok(())
482/// }
483/// ```
484///
485pub fn count_if<'a, const M: usize, const N: usize, C, U, F>(
486    re: U,
487    r#if: F,
488) -> crate::neu::NeureRepeat<M, N, C, U, F>
489where
490    C: Context<'a> + 'a,
491    U: Neu<C::Item>,
492    F: crate::neu::NeuCond<'a, C>,
493{
494    re.repeat::<M, N>().set_cond(r#if)
495}
496
497///
498/// Match the start position of data.
499///
500/// # Example
501///
502/// ```
503/// # use neure::prelude::*;
504/// #
505/// # fn main() -> color_eyre::Result<()> {
506/// #     color_eyre::install()?;
507///     let pos = re::start();
508///     let rust = re::string("rust");
509///     let year = neu::digit(10).repeat_times::<4>();
510///     let mut ctx = CharsCtx::new("rust2023");
511///
512///     assert_eq!(ctx.try_mat(&pos)?, Span::new(0, 0));
513///     assert_eq!(ctx.try_mat(&rust)?, Span::new(0, 4));
514///     assert_eq!(ctx.try_mat(&year)?, Span::new(4, 4));
515///
516///     Ok(())
517/// # }
518/// ```
519pub fn start() -> AnchorStart {
520    AnchorStart::new()
521}
522
523///
524/// Match the end position of data.
525///
526/// # Example
527///
528/// ```
529/// # use neure::prelude::*;
530/// #
531/// # fn main() -> color_eyre::Result<()> {
532/// #     color_eyre::install()?;
533///     let rust = re::string("rust");
534///     let year = neu::digit(10).repeat_times::<4>();
535///     let end = re::end();
536///     let mut ctx = CharsCtx::new("rust2023");
537///
538///     assert_eq!(ctx.try_mat(&rust)?, Span::new(0, 4));
539///     assert_eq!(ctx.try_mat(&year)?, Span::new(4, 4));
540///     assert_eq!(ctx.try_mat(&end)?, Span::new(8, 0));
541///
542///     Ok(())
543/// # }
544/// ```
545pub fn end() -> AnchorEnd {
546    AnchorEnd::new()
547}
548
549///
550/// Match given string.
551///
552/// # Example
553///
554/// ```
555/// # use neure::prelude::*;
556/// #
557/// # fn main() -> color_eyre::Result<()> {
558/// #     color_eyre::install()?;
559///     let rust = re::string("rust");
560///     let mut ctx = CharsCtx::new("rust2023");
561///
562///     assert_eq!(ctx.try_mat(&rust)?, Span::new(0, 4));
563///
564///     Ok(())
565/// # }
566/// ```
567pub fn string(lit: &str) -> LitString<'_> {
568    LitString::new(lit)
569}
570
571///
572/// Match given data.
573///
574/// # Example
575///
576/// ```
577/// # use neure::prelude::*;
578/// #
579/// # fn main() -> color_eyre::Result<()> {
580/// #     color_eyre::install()?;
581///     let head = re::lit_slice(&[0xff, 0xff]);
582///     let mut ctx = BytesCtx::new(&[0xff, 0xff, 0x12]);
583///
584///     assert_eq!(ctx.try_mat(&head)?, Span::new(0, 2));
585///
586///     Ok(())
587/// # }
588/// ```
589pub fn lit_slice<T>(lit: &[T]) -> LitSlice<'_, T> {
590    LitSlice::new(lit)
591}
592
593///
594/// Consume given length datas.
595///
596/// # Example
597///
598/// ```
599/// # use neure::prelude::*;
600/// #
601/// # fn main() -> color_eyre::Result<()> {
602/// #     color_eyre::install()?;
603///     let null = re::consume(6);
604///     let mut ctx = CharsCtx::new("aabbccgg");
605///
606///     assert_eq!(ctx.try_mat(&null)?, Span::new(0, 6));
607///
608///     Ok(())
609/// # }
610/// ```
611pub fn consume(len: usize) -> Consume {
612    Consume::new(len)
613}
614
615///
616/// Consume all the left datas.
617///
618/// # Example
619///
620/// ```
621/// # use neure::prelude::*;
622/// #
623/// # fn main() -> color_eyre::Result<()> {
624/// #     color_eyre::install()?;
625///     let str = re::string("aabb");
626///     let mut ctx = CharsCtx::new("aabbccgg");
627///
628///     assert_eq!(ctx.try_mat(&str.then(re::consume_all()))?, Span::new(0, 8));
629///
630///     Ok(())
631/// # }
632/// ```
633pub fn consume_all() -> ConsumeAll {
634    ConsumeAll::new()
635}
636
637///
638/// Match nothing, simple return `R::from(_, (0, 0))`.
639///
640/// # Example
641///
642/// ```
643/// # use neure::prelude::*;
644/// #
645/// # fn main() -> color_eyre::Result<()> {
646/// #     color_eyre::install()?;
647///     let null = re::null();
648///     let mut ctx = CharsCtx::new("aabbccgg");
649///
650///     assert_eq!(ctx.try_mat(&null)?, Span::new(0, 0));
651///
652///     Ok(())
653/// # }
654/// ```
655pub fn null<R>() -> NullRegex<R> {
656    NullRegex::new()
657}
658
659///
660/// Return a regex that reverses the result of `re`.
661/// It will return zero-length [`Span`] when matches.
662///
663/// # Example
664///
665/// ```
666/// # use neure::prelude::*;
667/// #
668/// # fn main() -> color_eyre::Result<()> {
669/// #     color_eyre::install()?;
670///     let re = re::not("]]]");
671///     let mut ctx = CharsCtx::new("[123,456,789]");
672///
673///     assert_eq!(ctx.try_mat(&re)?, Span::new(0, 0));
674///     Ok(())
675/// # }
676/// ```
677pub fn not<T>(re: T) -> RegexNot<T> {
678    RegexNot::new(re)
679}
680
681/// Iterate over the vector and match the regex against the [`Context`].
682/// It will return the result of first regex that matches.
683///
684/// # Example
685///
686/// ```
687/// # use neure::prelude::*;
688/// #
689/// # fn main() -> color_eyre::Result<()> {
690/// #     color_eyre::install()?;
691///     let ty = neu::ascii_alphabetic().repeat_one_more();
692///     let id = neu::ascii_alphabetic().repeat_one_more();
693///     let var = ty.sep_once("", id);
694///     let ptr = ty.sep_once("*", id);
695///     let r#ref = ty.sep_once("&", id);
696///     let vec = re::vector([var, ptr, r#ref]);
697///     let sp = neu::whitespace().repeat_full();
698///
699///     assert_eq!(CharsCtx::new("int a").ignore(sp).ctor(&vec)?, ("int", "a"));
700///     assert_eq!(CharsCtx::new("int *a").ignore(sp).ctor(&vec)?, ("int", "a"));
701///     assert_eq!(CharsCtx::new("int &a").ignore(sp).ctor(&vec)?, ("int", "a"));
702///     Ok(())
703/// # }
704/// ```
705pub fn vector<T>(val: impl IntoIterator<Item = T>) -> Vector<T> {
706    Vector::new(val.into_iter().collect())
707}
708
709/// Iterate over the vector and match the regex against the [`Context`].
710/// It will return the value of first pair that matches.
711///
712/// # Example
713///
714/// ```
715/// # use neure::prelude::*;
716/// #
717/// # fn main() -> color_eyre::Result<()> {
718/// #     color_eyre::install()?;
719///     #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
720///     pub enum C {
721///         Var,
722///         Ptr,
723///         Ref,
724///     }
725///
726///     let ty = neu::ascii_alphabetic().repeat_one_more();
727///     let id = neu::ascii_alphabetic().repeat_one_more();
728///     let var = ty.sep_once("", id);
729///     let ptr = ty.sep_once("*", id);
730///     let r#ref = ty.sep_once("&", id);
731///     let vec = re::pair_vector([(var, C::Var), (ptr, C::Ptr), (r#ref, C::Ref)]);
732///     let sp = neu::whitespace().repeat_full();
733///
734///     assert_eq!(
735///         CharsCtx::new("int a").ignore(sp).ctor(&vec)?,
736///         (("int", "a"), C::Var)
737///     );
738///     assert_eq!(
739///         CharsCtx::new("int *a").ignore(sp).ctor(&vec)?,
740///         (("int", "a"), C::Ptr)
741///     );
742///     assert_eq!(
743///         CharsCtx::new("int &a").ignore(sp).ctor(&vec)?,
744///         (("int", "a"), C::Ref)
745///     );
746///     Ok(())
747/// # }
748/// ```
749pub fn pair_vector<K, V: Clone>(val: impl IntoIterator<Item = (K, V)>) -> PairVector<K, V> {
750    PairVector::new(val.into_iter().collect())
751}
752
753pub fn array<const N: usize, T>(val: [T; N]) -> Array<N, T> {
754    Array::new(val)
755}
756
757pub fn slice<const N: usize, T>(val: &[T; N]) -> Slice<'_, N, T> {
758    Slice::new(val)
759}
760
761pub fn pair_array<const N: usize, K, V>(val: [(K, V); N]) -> PairArray<N, K, V> {
762    PairArray::new(val)
763}
764
765pub fn pair_slice<const N: usize, K, V>(val: &[(K, V); N]) -> PairSlice<'_, N, K, V> {
766    PairSlice::new(val)
767}
768
769#[cfg(feature = "log")]
770macro_rules! trace {
771    ($name:literal, $beg:ident, $ret:expr) => {{
772        let ret = $ret;
773        $crate::trace_log!("r`{}`@{} start", $name, $beg);
774        ret
775    }};
776    ($name:literal, $beg:ident @ $stage:literal, $ret:expr) => {{
777        let ret = $ret;
778        $crate::trace_log!("r`{}`@{} try stage `{}`", $name, $beg, $stage);
779        ret
780    }};
781    ($name:literal, $beg:ident -> $end:expr, $ret:expr) => {{
782        let ret = $ret;
783        $crate::trace_log!("r`{}`@{} -> {{end: {}, ret: {}}}", $name, $beg, $end, ret);
784        ret
785    }};
786    ($name:literal, $beg:ident => $end:expr, $ret:expr) => {{
787        let ret = $ret;
788        $crate::trace_log!("r`{}`@{} => {{end: {}, ret: {:?}}}", $name, $beg, $end, ret);
789        ret
790    }};
791}
792
793#[cfg(feature = "log")]
794macro_rules! trace_v {
795    ($name:literal, $inner:expr, $beg:ident, $ret:expr) => {{
796        let ret = $ret;
797        $crate::trace_log!("r`{}({:?})`@{} start", $name, $inner, $beg);
798        ret
799    }};
800    ($name:literal, $inner:expr, $beg:ident @ $stage:literal, $ret:expr) => {{
801        let ret = $ret;
802        $crate::trace_log!("r`{}({:?})`@{} try stage `{}`", $name, $inner, $beg, $stage);
803        ret
804    }};
805    ($name:literal, $inner:expr, $beg:ident => $end:expr, $ret:expr, $cnt:expr) => {{
806        let ret = $ret;
807        $crate::trace_log!(
808            "r`{}({:?})`@{} => {{end: {}, ret: {:?}, cnt = {}}}",
809            $name,
810            $inner,
811            $beg,
812            $end,
813            ret,
814            $cnt
815        );
816        ret
817    }};
818    ($name:literal, $inner:expr, $beg:ident -> $end:expr, $ret:expr, $cnt:expr) => {{
819        let ret = $ret;
820        $crate::trace_log!(
821            "r`{}({:?})`@{} -> {{end: {}, ret: {}, cnt: {}}}",
822            $name,
823            $inner,
824            $beg,
825            $end,
826            ret,
827            $cnt
828        );
829        ret
830    }};
831}
832
833#[cfg(not(feature = "log"))]
834macro_rules! trace {
835    ($name:literal, $beg:ident, $ret:expr) => {{
836        let (_, _, ret) = ($name, $beg, $ret);
837        ret
838    }};
839    ($name:literal, $beg:ident @ $stage:literal, $ret:expr) => {{
840        let (_, _, _, ret) = ($name, $beg, $stage, $ret);
841        ret
842    }};
843    ($name:literal, $beg:ident -> $end:expr, $ret:expr) => {{
844        let (_, _, _, ret) = ($name, $beg, $end, $ret);
845        ret
846    }};
847    ($name:literal, $beg:ident => $end:expr, $ret:expr) => {{
848        let (_, _, _, ret) = ($name, $beg, $end, $ret);
849        ret
850    }};
851}
852
853#[cfg(not(feature = "log"))]
854macro_rules! trace_v {
855    ($name:literal, $inner:expr, $beg:ident, $ret:expr) => {{
856        let (_, _, _, ret) = ($name, $inner, $beg, $ret);
857        ret
858    }};
859    ($name:literal, $inner:expr, $beg:ident @ $stage:literal, $ret:expr) => {{
860        let (_, _, _, _, ret) = ($name, $inner, $beg, $stage, $ret);
861        ret
862    }};
863    ($name:literal, $inner:expr, $beg:ident => $end:expr, $ret:expr, $cnt:expr) => {{
864        let (_, _, _, _, ret) = ($name, $inner, $beg, $end, $ret);
865        ret
866    }};
867    ($name:literal, $inner:expr, $beg:ident -> $end:expr, $ret:expr, $cnt:expr) => {{
868        let (_, _, _, _, ret) = ($name, $inner, $beg, $end, $ret);
869        ret
870    }};
871}
872
873macro_rules! def_not {
874    (@$ty:ident [ ]  [ ]) => {
875        impl std::ops::Not for $ty {
876            type Output = $crate::re::RegexNot<Self>;
877
878            fn not(self) -> Self::Output { $crate::re::not(self) }
879        }
880    };
881    (@$ty:ident [ ]  [ $($p:ident),+ ]) => {
882        impl<$($p),+> std::ops::Not for $ty<$($p),+> {
883            type Output = $crate::re::RegexNot<Self>;
884
885            fn not(self) -> Self::Output { $crate::re::not(self) }
886        }
887    };
888    (@$ty:ident [ $($l:lifetime),+ ]  [ $($p:ident),* ]) => {
889        impl<$($l),+ , $($p),*> std::ops::Not for $ty<$($l),+ , $($p),*> {
890            type Output = $crate::re::RegexNot<Self>;
891
892            fn not(self) -> Self::Output { $crate::re::not(self) }
893        }
894    };
895    ($ty:ident) => {
896        def_not! { @$ty [ ] [ ] }
897    };
898    ($ty:ident < $($l:lifetime),* $(,)? $($p:ident),* >) => {
899        def_not! { @$ty [$($l),*] [$($p),*] }
900    };
901}
902
903pub(crate) use def_not;
904pub(crate) use trace;
905pub(crate) use trace_v;