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
305pub 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
336pub 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
368pub 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
398pub 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
427pub 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
456pub 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
497pub fn start() -> AnchorStart {
520 AnchorStart::new()
521}
522
523pub fn end() -> AnchorEnd {
546 AnchorEnd::new()
547}
548
549pub fn string(lit: &str) -> LitString<'_> {
568 LitString::new(lit)
569}
570
571pub fn lit_slice<T>(lit: &[T]) -> LitSlice<'_, T> {
590 LitSlice::new(lit)
591}
592
593pub fn consume(len: usize) -> Consume {
612 Consume::new(len)
613}
614
615pub fn consume_all() -> ConsumeAll {
634 ConsumeAll::new()
635}
636
637pub fn null<R>() -> NullRegex<R> {
656 NullRegex::new()
657}
658
659pub fn not<T>(re: T) -> RegexNot<T> {
678 RegexNot::new(re)
679}
680
681pub fn vector<T>(val: impl IntoIterator<Item = T>) -> Vector<T> {
706 Vector::new(val.into_iter().collect())
707}
708
709pub 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;