neure/
lib.rs

1#![doc = include_str!("../README.md")]
2pub mod ctx;
3pub mod err;
4pub mod iter;
5pub mod r#macro;
6pub mod map;
7pub mod neu;
8pub mod re;
9pub mod span;
10
11#[cfg(feature = "log")]
12pub(crate) use tracing::trace as trace_log;
13#[cfg(not(feature = "log"))]
14#[macro_use]
15pub(crate) mod log {
16    #[macro_export]
17    macro_rules! trace_log {
18        ($($arg:tt)*) => {
19            ();
20        };
21    }
22}
23
24#[cfg(feature = "log")]
25pub trait MayDebug: std::fmt::Debug {}
26
27#[cfg(feature = "log")]
28impl<T> MayDebug for T where T: std::fmt::Debug {}
29
30#[cfg(not(feature = "log"))]
31pub trait MayDebug {}
32
33#[cfg(not(feature = "log"))]
34impl<T> MayDebug for T {}
35
36pub use charize::charize;
37pub mod prelude {
38    pub use crate::ctx::BytesCtx;
39    pub use crate::ctx::CharsCtx;
40    pub use crate::ctx::Context;
41    pub use crate::ctx::Match;
42    pub use crate::ctx::RegexCtx;
43    pub use crate::ctx::Ret;
44    pub use crate::ctx::Span;
45    pub use crate::map;
46    pub use crate::neu;
47    pub use crate::neu::Condition;
48    pub use crate::neu::Neu;
49    pub use crate::neu::Neu2Re;
50    pub use crate::neu::NeuCond;
51    pub use crate::neu::NeuOp;
52    pub use crate::re;
53    pub use crate::re::ConstructIntoOp;
54    pub use crate::re::ConstructOp;
55    pub use crate::re::Regex;
56    pub use crate::re::RegexIntoOp;
57    pub use crate::span::SimpleStorer;
58}
59
60#[cfg(test)]
61mod test {
62
63    use crate::prelude::*;
64    use crate::re;
65
66    #[test]
67    fn test_all() {
68        assert!(test_space().is_ok());
69        assert!(test_char().is_ok());
70        assert!(test_chars().is_ok());
71        assert!(test_chars_negative().is_ok());
72        assert!(test_range().is_ok());
73        assert!(test_range_negative().is_ok());
74        assert!(test_other().is_ok());
75    }
76
77    macro_rules! test_t {
78        ($ctx:ident, $storer:ident, $str:literal, $id:literal, $parser:expr) => {
79            let space_parser = $parser;
80
81            $ctx.reset_with($str);
82            $storer.reset();
83            assert!($storer.try_cap($id, &mut $ctx, &space_parser).is_err());
84        };
85        ($ctx:ident, $storer:ident, $str:literal, $id:literal, $parser:expr, $($span:expr)*) => {
86            let space_parser = $parser;
87
88            $ctx.reset_with($str);
89            $storer.reset();
90            $storer.try_cap($id, &mut $ctx, &space_parser)?;
91            assert_eq!($storer.spans_iter($id).unwrap().collect::<Vec<_>>(), vec![$($span)*])
92        };
93    }
94
95    fn test_other() -> Result<(), Box<dyn std::error::Error>> {
96        let mut ctx = RegexCtx::new("");
97        let mut storer = SimpleStorer::new(1);
98
99        test_t!(ctx, storer, "abedf", 0, re!(.), Span { beg: 0, len: 1 });
100        test_t!(ctx, storer, "abedf", 0, re!(.?), Span { beg: 0, len: 1 });
101        test_t!(ctx, storer, "\nabedf", 0, re!(.?), Span { beg: 0, len: 0 });
102        test_t!(ctx, storer, "abedf", 0, re!(.*), Span { beg: 0, len: 5 });
103        test_t!(ctx, storer, "\nabedf", 0, re!(.*), Span { beg: 0, len: 0 });
104        test_t!(ctx, storer, "abedf", 0, re!(.+), Span { beg: 0, len: 5 });
105        test_t!(ctx, storer, "\nabedf", 0, re!(.+));
106        test_t!(ctx, storer, "abedf", 0, re!(.{2}), Span { beg: 0, len: 2 });
107        test_t!(ctx, storer, "ab\nedf", 0, re!(.{3}));
108        test_t!(ctx, storer, "abedf", 0, re!(.{2,}), Span { beg: 0, len: 5 });
109        test_t!(
110            ctx,
111            storer,
112            "abedf",
113            0,
114            re!(.{4,6}),
115            Span { beg: 0, len: 5 }
116        );
117        test_t!(ctx, storer, "abe\ndf", 0, re!(.{4,6}));
118        test_t!(ctx, storer, "c\nabedf", 0, re!(^), Span { beg: 0, len: 1 });
119
120        Ok(())
121    }
122
123    fn test_range_negative() -> Result<(), Box<dyn std::error::Error>> {
124        let mut ctx = RegexCtx::new("");
125        let mut storer = SimpleStorer::new(1);
126
127        test_t!(
128            ctx,
129            storer,
130            "Raefc",
131            0,
132            re!([^a - z]),
133            Span { beg: 0, len: 1 }
134        );
135        test_t!(
136            ctx,
137            storer,
138            "你aefc",
139            0,
140            re!([^a - z A - Z]),
141            Span { beg: 0, len: 3 }
142        );
143        test_t!(
144            ctx,
145            storer,
146            "aefc",
147            0,
148            re!([^a - z]?),
149            Span { beg: 0, len: 0 }
150        );
151        test_t!(
152            ctx,
153            storer,
154            "AEUF",
155            0,
156            re!([^a - z]?),
157            Span { beg: 0, len: 1 }
158        );
159        test_t!(
160            ctx,
161            storer,
162            "&AEUF",
163            0,
164            re!([^a - z A - Z]),
165            Span { beg: 0, len: 1 }
166        );
167        test_t!(
168            ctx,
169            storer,
170            "AEUF",
171            0,
172            re!([^a-z]*),
173            Span { beg: 0, len: 4 }
174        );
175        test_t!(
176            ctx,
177            storer,
178            "aefc",
179            0,
180            re!([^a-z]*),
181            Span { beg: 0, len: 0 }
182        );
183        test_t!(
184            ctx,
185            storer,
186            "@#$%",
187            0,
188            re!([^a - z A - Z]*),
189            Span { beg: 0, len: 4 }
190        );
191        test_t!(
192            ctx,
193            storer,
194            "AEUF",
195            0,
196            re!([^a-z]+),
197            Span { beg: 0, len: 4 }
198        );
199        test_t!(ctx, storer, "aefc", 0, re!([^a-z]+));
200        test_t!(
201            ctx,
202            storer,
203            "AEUF",
204            0,
205            re!([^a-z]{3}),
206            Span { beg: 0, len: 3 }
207        );
208        test_t!(ctx, storer, "aefc", 0, re!([^a-z]{3}));
209        test_t!(
210            ctx,
211            storer,
212            "AEUF",
213            0,
214            re!([^a-z]{3,6}),
215            Span { beg: 0, len: 4 }
216        );
217        test_t!(ctx, storer, "aefc", 0, re!([^a-z]{3,6}));
218        test_t!(
219            ctx,
220            storer,
221            "AEUF",
222            0,
223            re!([^a-z]{3,}),
224            Span { beg: 0, len: 4 }
225        );
226        test_t!(ctx, storer, "aefc", 0, re!([^a-z]{3,}));
227
228        test_t!(
229            ctx,
230            storer,
231            "@#$%",
232            0,
233            re!([^'a' - 'z' 'A' - 'Z']*),
234            Span { beg: 0, len: 4 }
235        );
236        test_t!(
237            ctx,
238            storer,
239            "AEUF",
240            0,
241            re!([^'a'-'z']+),
242            Span { beg: 0, len: 4 }
243        );
244        test_t!(ctx, storer, "aefc", 0, re!([^'a'-'z']+));
245        test_t!(
246            ctx,
247            storer,
248            "AEUF",
249            0,
250            re!([^'a'-'z']{3}),
251            Span { beg: 0, len: 3 }
252        );
253        test_t!(ctx, storer, "aefc", 0, re!([^'a'-'z']{3}));
254        test_t!(
255            ctx,
256            storer,
257            "AEUF",
258            0,
259            re!([^'a'-'z']{3,6}),
260            Span { beg: 0, len: 4 }
261        );
262        test_t!(ctx, storer, "aefc", 0, re!([^'a'-'z']{3,6}));
263        test_t!(
264            ctx,
265            storer,
266            "AEUF",
267            0,
268            re!([^'a'-'z']{3,}),
269            Span { beg: 0, len: 4 }
270        );
271        test_t!(ctx, storer, "aefc", 0, re!([^'a'-'z']{3,}));
272        Ok(())
273    }
274
275    fn test_range() -> Result<(), Box<dyn std::error::Error>> {
276        let mut ctx = RegexCtx::new("");
277        let mut storer = SimpleStorer::new(1);
278
279        test_t!(
280            ctx,
281            storer,
282            "aefc",
283            0,
284            re!([a - z]),
285            Span { beg: 0, len: 1 }
286        );
287        test_t!(
288            ctx,
289            storer,
290            "aefc",
291            0,
292            re!([a - z A - Z]),
293            Span { beg: 0, len: 1 }
294        );
295        test_t!(
296            ctx,
297            storer,
298            "aefc",
299            0,
300            re!([a - z]?),
301            Span { beg: 0, len: 1 }
302        );
303        test_t!(
304            ctx,
305            storer,
306            "AEUF",
307            0,
308            re!([a - z]?),
309            Span { beg: 0, len: 0 }
310        );
311        test_t!(
312            ctx,
313            storer,
314            "AEUF",
315            0,
316            re!([a - z A - Z]),
317            Span { beg: 0, len: 1 }
318        );
319        test_t!(ctx, storer, "aefc", 0, re!([a-z]*), Span { beg: 0, len: 4 });
320        test_t!(ctx, storer, "AEUF", 0, re!([a-z]*), Span { beg: 0, len: 0 });
321        test_t!(
322            ctx,
323            storer,
324            "AEUF",
325            0,
326            re!([a - z A - Z]*),
327            Span { beg: 0, len: 4 }
328        );
329        test_t!(ctx, storer, "aefc", 0, re!([a-z]+), Span { beg: 0, len: 4 });
330        test_t!(ctx, storer, "AEUF", 0, re!([a-z]+));
331        test_t!(
332            ctx,
333            storer,
334            "aefc",
335            0,
336            re!([a-z]{3}),
337            Span { beg: 0, len: 3 }
338        );
339        test_t!(ctx, storer, "AEUF", 0, re!([a-z]{3}));
340        test_t!(
341            ctx,
342            storer,
343            "aefc",
344            0,
345            re!([a-z]{3,6}),
346            Span { beg: 0, len: 4 }
347        );
348        test_t!(ctx, storer, "AEUF", 0, re!([a-z]{3,6}));
349        test_t!(
350            ctx,
351            storer,
352            "aefc",
353            0,
354            re!([a-z]{3,}),
355            Span { beg: 0, len: 4 }
356        );
357        test_t!(ctx, storer, "AEUF", 0, re!([a-z]{3,}));
358
359        test_t!(
360            ctx,
361            storer,
362            "aefc",
363            0,
364            re!(['a' - 'z']),
365            Span { beg: 0, len: 1 }
366        );
367        test_t!(
368            ctx,
369            storer,
370            "aefc",
371            0,
372            re!(['a' - 'z']?),
373            Span { beg: 0, len: 1 }
374        );
375        test_t!(
376            ctx,
377            storer,
378            "AEUF",
379            0,
380            re!(['a' - 'z']?),
381            Span { beg: 0, len: 0 }
382        );
383        test_t!(
384            ctx,
385            storer,
386            "aefc",
387            0,
388            re!(['a'-'z']*),
389            Span { beg: 0, len: 4 }
390        );
391        test_t!(
392            ctx,
393            storer,
394            "AEUF",
395            0,
396            re!(['a'-'z']*),
397            Span { beg: 0, len: 0 }
398        );
399        test_t!(
400            ctx,
401            storer,
402            "aefc",
403            0,
404            re!(['a'-'z']+),
405            Span { beg: 0, len: 4 }
406        );
407        test_t!(ctx, storer, "AEUF", 0, re!(['a'-'z']+));
408        test_t!(
409            ctx,
410            storer,
411            "AEUF",
412            0,
413            re!(['a'-'z''A'-'Z']+),
414            Span { beg: 0, len: 4 }
415        );
416        test_t!(
417            ctx,
418            storer,
419            "aefc",
420            0,
421            re!(['a'-'z']{3}),
422            Span { beg: 0, len: 3 }
423        );
424        test_t!(ctx, storer, "AEUF", 0, re!(['a'-'z']{3}));
425        test_t!(
426            ctx,
427            storer,
428            "aefc",
429            0,
430            re!(['a'-'z']{3,6}),
431            Span { beg: 0, len: 4 }
432        );
433        test_t!(ctx, storer, "AEUF", 0, re!(['a'-'z']{3,6}));
434        test_t!(
435            ctx,
436            storer,
437            "aefc",
438            0,
439            re!(['a'-'z']{3,}),
440            Span { beg: 0, len: 4 }
441        );
442        test_t!(ctx, storer, "AEUF", 0, re!(['a'-'z']{3,}));
443
444        Ok(())
445    }
446
447    fn test_chars_negative() -> Result<(), Box<dyn std::error::Error>> {
448        let mut ctx = RegexCtx::new("");
449        let mut storer = SimpleStorer::new(1);
450
451        test_t!(
452            ctx,
453            storer,
454            "aefc",
455            0,
456            re!([^b c d]),
457            Span { beg: 0, len: 1 }
458        );
459        test_t!(
460            ctx,
461            storer,
462            "aefc",
463            0,
464            re!([^b c d]?),
465            Span { beg: 0, len: 1 }
466        );
467        test_t!(
468            ctx,
469            storer,
470            "aefc",
471            0,
472            re!([^'b' 'c' 'd']),
473            Span { beg: 0, len: 1 }
474        );
475        test_t!(
476            ctx,
477            storer,
478            "aefc",
479            0,
480            re!([^'b' 'c' 'd']?),
481            Span { beg: 0, len: 1 }
482        );
483        test_t!(
484            ctx,
485            storer,
486            "daefc",
487            0,
488            re!([^b c d]?),
489            Span { beg: 0, len: 0 }
490        );
491        test_t!(
492            ctx,
493            storer,
494            "aefc",
495            0,
496            re!([^b c d]*),
497            Span { beg: 0, len: 3 }
498        );
499        test_t!(
500            ctx,
501            storer,
502            "daefc",
503            0,
504            re!([^b c d]*),
505            Span { beg: 0, len: 0 }
506        );
507        test_t!(
508            ctx,
509            storer,
510            "aefc",
511            0,
512            re!([^b c d]+),
513            Span { beg: 0, len: 3 }
514        );
515        test_t!(
516            ctx,
517            storer,
518            "aefcddd",
519            0,
520            re!([^b c d]+),
521            Span { beg: 0, len: 3 }
522        );
523        test_t!(ctx, storer, "baefcddd", 0, re!([^b c d]+));
524        test_t!(
525            ctx,
526            storer,
527            "aefh",
528            0,
529            re!([^b c d]{4}),
530            Span { beg: 0, len: 4 }
531        );
532        test_t!(
533            ctx,
534            storer,
535            "aefhcc",
536            0,
537            re!([^b c d]{4,}),
538            Span { beg: 0, len: 4 }
539        );
540        test_t!(
541            ctx,
542            storer,
543            "aefhccd",
544            0,
545            re!([^b c d]{4,7}),
546            Span { beg: 0, len: 4 }
547        );
548        test_t!(ctx, storer, "aecfhccd", 0, re!([^b c d]{4,7}));
549        Ok(())
550    }
551
552    fn test_chars() -> Result<(), Box<dyn std::error::Error>> {
553        let mut ctx = RegexCtx::new("");
554        let mut storer = SimpleStorer::new(1);
555
556        test_t!(
557            ctx,
558            storer,
559            "dabcd",
560            0,
561            re!([b c d]),
562            Span { beg: 0, len: 1 }
563        );
564        test_t!(
565            ctx,
566            storer,
567            "dabcd",
568            0,
569            re!([b c d]?),
570            Span { beg: 0, len: 1 }
571        );
572        test_t!(
573            ctx,
574            storer,
575            "edabcd",
576            0,
577            re!([b c d]?),
578            Span { beg: 0, len: 0 }
579        );
580        test_t!(
581            ctx,
582            storer,
583            "dbcd",
584            0,
585            re!([b c d]*),
586            Span { beg: 0, len: 4 }
587        );
588        test_t!(
589            ctx,
590            storer,
591            "aeuyf",
592            0,
593            re!([b c d]*),
594            Span { beg: 0, len: 0 }
595        );
596        test_t!(
597            ctx,
598            storer,
599            "dabcd",
600            0,
601            re!([b c d]+),
602            Span { beg: 0, len: 1 }
603        );
604        test_t!(
605            ctx,
606            storer,
607            "dbcdfff",
608            0,
609            re!([b c d]+),
610            Span { beg: 0, len: 4 }
611        );
612        test_t!(ctx, storer, "abcd", 0, re!([b c d]+));
613        test_t!(
614            ctx,
615            storer,
616            "dbcd",
617            0,
618            re!([b c d]{4}),
619            Span { beg: 0, len: 4 }
620        );
621        test_t!(
622            ctx,
623            storer,
624            "dbcdccc",
625            0,
626            re!([b c d]{4,}),
627            Span { beg: 0, len: 7 }
628        );
629        test_t!(
630            ctx,
631            storer,
632            "dbcdbb",
633            0,
634            re!([b c d]{4,7}),
635            Span { beg: 0, len: 6 }
636        );
637
638        test_t!(
639            ctx,
640            storer,
641            "dabcd",
642            0,
643            re!(['b' 'c' 'd']),
644            Span { beg: 0, len: 1 }
645        );
646        test_t!(
647            ctx,
648            storer,
649            "dabcd",
650            0,
651            re!(['b' 'c' 'd']?),
652            Span { beg: 0, len: 1 }
653        );
654        test_t!(
655            ctx,
656            storer,
657            "edabcd",
658            0,
659            re!(['b' 'c' 'd']?),
660            Span { beg: 0, len: 0 }
661        );
662        test_t!(
663            ctx,
664            storer,
665            "dbcd",
666            0,
667            re!(['b' 'c' 'd']*),
668            Span { beg: 0, len: 4 }
669        );
670        test_t!(
671            ctx,
672            storer,
673            "aeuyf",
674            0,
675            re!(['b' 'c' 'd']*),
676            Span { beg: 0, len: 0 }
677        );
678        test_t!(
679            ctx,
680            storer,
681            "dabcd",
682            0,
683            re!(['b' 'c' 'd']+),
684            Span { beg: 0, len: 1 }
685        );
686        test_t!(
687            ctx,
688            storer,
689            "dbcdfff",
690            0,
691            re!(['b' 'c' 'd']+),
692            Span { beg: 0, len: 4 }
693        );
694        test_t!(ctx, storer, "abcd", 0, re!(['b' 'c' 'd']+));
695        test_t!(
696            ctx,
697            storer,
698            "dbcd",
699            0,
700            re!(['b' 'c' 'd']{4}),
701            Span { beg: 0, len: 4 }
702        );
703        test_t!(
704            ctx,
705            storer,
706            "dbcdccc",
707            0,
708            re!(['b' 'c' 'd']{4,}),
709            Span { beg: 0, len: 7 }
710        );
711        test_t!(
712            ctx,
713            storer,
714            "dbcdbb",
715            0,
716            re!(['b' 'c' 'd']{4,7}),
717            Span { beg: 0, len: 6 }
718        );
719        Ok(())
720    }
721
722    fn test_char() -> Result<(), Box<dyn std::error::Error>> {
723        let mut ctx = RegexCtx::new("");
724        let mut storer = SimpleStorer::new(1);
725
726        test_t!(ctx, storer, "a", 0, re!(a), Span { beg: 0, len: 1 });
727        test_t!(ctx, storer, "a", 0, re!('a'), Span { beg: 0, len: 1 });
728        test_t!(ctx, storer, "a", 0, re!(a?), Span { beg: 0, len: 1 });
729        test_t!(ctx, storer, "a", 0, re!('a'?), Span { beg: 0, len: 1 });
730        test_t!(ctx, storer, "你", 0, re!(你), Span { beg: 0, len: 3 });
731        test_t!(ctx, storer, "你you", 0, re!('你'), Span { beg: 0, len: 3 });
732        test_t!(ctx, storer, "@", 0, re!('@'), Span { beg: 0, len: 1 });
733        test_t!(ctx, storer, "der", 0, re!(a?), Span { beg: 0, len: 0 });
734        test_t!(ctx, storer, "", 0, re!('a'?), Span { beg: 0, len: 0 });
735        test_t!(ctx, storer, "a", 0, re!(a*), Span { beg: 0, len: 1 });
736        test_t!(
737            ctx,
738            storer,
739            "aaaaaee",
740            0,
741            re!('a'*),
742            Span { beg: 0, len: 5 }
743        );
744        test_t!(ctx, storer, "cde", 0, re!(a*), Span { beg: 0, len: 0 });
745        test_t!(ctx, storer, "aaaaee", 0, re!('a'+), Span { beg: 0, len: 4 });
746        test_t!(ctx, storer, "你你你", 0, re!(你+), Span { beg: 0, len: 9 });
747        test_t!(ctx, storer, "我你你你", 0, re!(你+));
748        test_t!(
749            ctx,
750            storer,
751            "aaaaee",
752            0,
753            re!('a'{2}),
754            Span { beg: 0, len: 2 }
755        );
756        test_t!(
757            ctx,
758            storer,
759            "你你你",
760            0,
761            re!(你{2}),
762            Span { beg: 0, len: 6 }
763        );
764        test_t!(ctx, storer, "你", 0, re!(你{2}));
765        test_t!(
766            ctx,
767            storer,
768            "aaaaee",
769            0,
770            re!('a'{2,}),
771            Span { beg: 0, len: 4 }
772        );
773        test_t!(
774            ctx,
775            storer,
776            "你你你",
777            0,
778            re!(你{2,}),
779            Span { beg: 0, len: 9 }
780        );
781        test_t!(ctx, storer, "你", 0, re!(你{2,}));
782        test_t!(
783            ctx,
784            storer,
785            "aaaaee",
786            0,
787            re!('a'{2,3}),
788            Span { beg: 0, len: 3 }
789        );
790        test_t!(
791            ctx,
792            storer,
793            "你你你你你啊",
794            0,
795            re!(你{2,4}),
796            Span { beg: 0, len: 12 }
797        );
798        test_t!(ctx, storer, "你啊", 0, re!(你{2,4}));
799
800        Ok(())
801    }
802
803    fn test_space() -> Result<(), Box<dyn std::error::Error>> {
804        let mut ctx = RegexCtx::new("");
805        let mut storer = SimpleStorer::new(1);
806
807        test_t!(ctx, storer, "\tcd", 0, re!(), Span { beg: 0, len: 1 });
808        test_t!(ctx, storer, "\tdwq", 0, re!(?), Span { beg: 0, len: 1 });
809        test_t!(ctx, storer, "dwq", 0, re!(?), Span { beg: 0, len: 0 });
810        test_t!(ctx, storer, "\t\n\rdda", 0, re!(*), Span { beg: 0, len: 3 });
811        test_t!(ctx, storer, "dda", 0, re!(*), Span { beg: 0, len: 0 });
812        test_t!(ctx, storer, "\t\n\rdda", 0, re!(+), Span { beg: 0, len: 3 });
813        test_t!(ctx, storer, "\tdda", 0, re!(+), Span { beg: 0, len: 1 });
814        test_t!(ctx, storer, "dda", 0, re!(+));
815        test_t!(
816            ctx,
817            storer,
818            " \u{A0}dda",
819            0,
820            re!({ 2 }),
821            Span { beg: 0, len: 3 }
822        );
823        test_t!(ctx, storer, "\u{A0}dda", 0, re!({ 2 }));
824        test_t!(
825            ctx,
826            storer,
827            "\t\rdda",
828            0,
829            re!({2,}),
830            Span { beg: 0, len: 2 }
831        );
832        test_t!(
833            ctx,
834            storer,
835            "\t\r\u{A0}dda",
836            0,
837            re!({2,}),
838            Span { beg: 0, len: 4 }
839        );
840        test_t!(ctx, storer, "dda", 0, re!());
841        test_t!(
842            ctx,
843            storer,
844            "\t\ndda",
845            0,
846            re!({2,3}),
847            Span { beg: 0, len: 2 }
848        );
849        test_t!(
850            ctx,
851            storer,
852            "\t\r\u{A0}dda",
853            0,
854            re!({2,3}),
855            Span { beg: 0, len: 4 }
856        );
857        test_t!(
858            ctx,
859            storer,
860            "\t\r \u{A0}dda",
861            0,
862            re!({2,3}),
863            Span { beg: 0, len: 3 }
864        );
865        test_t!(ctx, storer, " dda", 0, re!({2,3}));
866
867        Ok(())
868    }
869}