1pub mod complete;
4pub mod streaming;
5#[cfg(test)]
6mod tests;
7
8use core::marker::PhantomData;
9
10use crate::error::ErrorKind;
11use crate::error::ParseError;
12use crate::internal::{Err, Needed, Parser};
13use crate::lib::std::result::Result::*;
14use crate::traits::{Compare, CompareResult};
15use crate::AsChar;
16use crate::Check;
17use crate::ExtendInto;
18use crate::FindSubstring;
19use crate::FindToken;
20use crate::Input;
21use crate::IsStreaming;
22use crate::Mode;
23use crate::OutputM;
24use crate::OutputMode;
25use crate::ToUsize;
26
27pub fn tag<T, I, Error: ParseError<I>>(tag: T) -> impl Parser<I, Output = I, Error = Error>
46where
47 I: Input + Compare<T>,
48 T: Input + Clone,
49{
50 Tag {
51 tag,
52 e: PhantomData,
53 }
54}
55
56pub struct Tag<T, E> {
58 tag: T,
59 e: PhantomData<E>,
60}
61
62impl<I, Error: ParseError<I>, T> Parser<I> for Tag<T, Error>
63where
64 I: Input + Compare<T>,
65 T: Input + Clone,
66{
67 type Output = I;
68
69 type Error = Error;
70
71 fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> {
72 let tag_len = self.tag.input_len();
73 let t = self.tag.clone();
74
75 match i.compare(t) {
76 CompareResult::Ok => Ok((i.take_from(tag_len), OM::Output::bind(|| i.take(tag_len)))),
77 CompareResult::Incomplete => {
78 if OM::Incomplete::is_streaming() {
79 Err(Err::Incomplete(Needed::new(tag_len - i.input_len())))
80 } else {
81 Err(Err::Error(OM::Error::bind(|| {
82 let e: ErrorKind = ErrorKind::Tag;
83 Error::from_error_kind(i, e)
84 })))
85 }
86 }
87 CompareResult::Error => Err(Err::Error(OM::Error::bind(|| {
88 let e: ErrorKind = ErrorKind::Tag;
89 Error::from_error_kind(i, e)
90 }))),
91 }
92 }
93}
94
95pub fn tag_no_case<T, I, Error: ParseError<I>>(tag: T) -> impl Parser<I, Output = I, Error = Error>
115where
116 I: Input + Compare<T>,
117 T: Input + Clone,
118{
119 TagNoCase {
120 tag,
121 e: PhantomData,
122 }
123}
124
125pub struct TagNoCase<T, E> {
127 tag: T,
128 e: PhantomData<E>,
129}
130
131impl<I, Error: ParseError<I>, T> Parser<I> for TagNoCase<T, Error>
132where
133 I: Input + Compare<T>,
134 T: Input + Clone,
135{
136 type Output = I;
137
138 type Error = Error;
139
140 fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> {
141 let tag_len = self.tag.input_len();
142 let t = self.tag.clone();
143
144 match i.compare_no_case(t) {
145 CompareResult::Ok => Ok((i.take_from(tag_len), OM::Output::bind(|| i.take(tag_len)))),
146 CompareResult::Incomplete => {
147 if OM::Incomplete::is_streaming() {
148 Err(Err::Incomplete(Needed::new(tag_len - i.input_len())))
149 } else {
150 Err(Err::Error(OM::Error::bind(|| {
151 let e: ErrorKind = ErrorKind::Tag;
152 Error::from_error_kind(i, e)
153 })))
154 }
155 }
156 CompareResult::Error => Err(Err::Error(OM::Error::bind(|| {
157 let e: ErrorKind = ErrorKind::Tag;
158 Error::from_error_kind(i, e)
159 }))),
160 }
161 }
162}
163
164pub struct SplitPosition<F, E> {
166 predicate: F,
167 error: PhantomData<E>,
168}
169
170impl<I, Error: ParseError<I>, F> Parser<I> for SplitPosition<F, Error>
171where
172 I: Input,
173 F: Fn(<I as Input>::Item) -> bool,
174{
175 type Output = I;
176
177 type Error = Error;
178
179 #[inline(always)]
180 fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> {
181 i.split_at_position_mode::<OM, _, _>(|c| (self.predicate)(c))
182 }
183}
184
185pub struct SplitPosition1<F, E> {
187 e: ErrorKind,
188 predicate: F,
189 error: PhantomData<E>,
190}
191
192impl<I, Error: ParseError<I>, F> Parser<I> for SplitPosition1<F, Error>
193where
194 I: Input,
195 F: Fn(<I as Input>::Item) -> bool,
196{
197 type Output = I;
198
199 type Error = Error;
200
201 #[inline(always)]
202 fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> {
203 i.split_at_position_mode1::<OM, _, _>(|c| (self.predicate)(c), self.e)
204 }
205}
206
207pub fn is_not<T, I, Error: ParseError<I>>(arr: T) -> impl Parser<I, Output = I, Error = Error>
229where
230 I: Input,
231 T: FindToken<<I as Input>::Item>,
232{
233 SplitPosition1 {
234 e: ErrorKind::IsNot,
235 predicate: move |c| arr.find_token(c),
236 error: PhantomData,
237 }
238}
239
240pub fn is_a<T, I, Error: ParseError<I>>(arr: T) -> impl Parser<I, Output = I, Error = Error>
262where
263 I: Input,
264 T: FindToken<<I as Input>::Item>,
265{
266 SplitPosition1 {
267 e: ErrorKind::IsA,
268 predicate: move |c| !arr.find_token(c),
269 error: PhantomData,
270 }
271}
272
273pub fn take_while<F, I, Error: ParseError<I>>(cond: F) -> impl Parser<I, Output = I, Error = Error>
293where
294 I: Input,
295 F: Fn(<I as Input>::Item) -> bool,
296{
297 SplitPosition {
298 predicate: move |c| !cond(c),
299 error: PhantomData,
300 }
301}
302
303pub fn take_while1<F, I, Error: ParseError<I>>(cond: F) -> impl Parser<I, Output = I, Error = Error>
328where
329 I: Input,
330 F: Fn(<I as Input>::Item) -> bool,
331{
332 SplitPosition1 {
333 e: ErrorKind::TakeWhile1,
334 predicate: move |c| !cond(c),
335 error: PhantomData,
336 }
337}
338
339pub fn take_while_m_n<F, I, Error: ParseError<I>>(
365 m: usize,
366 n: usize,
367 predicate: F,
368) -> impl Parser<I, Output = I, Error = Error>
369where
370 I: Input,
371 F: Fn(<I as Input>::Item) -> bool,
372{
373 TakeWhileMN {
374 m,
375 n,
376 predicate,
377 e: PhantomData,
378 }
379}
380
381pub struct TakeWhileMN<F, E> {
383 m: usize,
384 n: usize,
385 predicate: F,
386 e: PhantomData<E>,
387}
388
389impl<I, Error: ParseError<I>, F> Parser<I> for TakeWhileMN<F, Error>
390where
391 I: Input,
392 F: Fn(<I as Input>::Item) -> bool,
393{
394 type Output = I;
395 type Error = Error;
396
397 fn process<OM: OutputMode>(
398 &mut self,
399 input: I,
400 ) -> crate::PResult<OM, I, Self::Output, Self::Error> {
401 let mut count = 0;
402 for (i, (index, item)) in input.iter_indices().enumerate() {
403 if i == self.n {
404 return Ok((
405 input.take_from(index),
406 OM::Output::bind(|| input.take(index)),
407 ));
408 }
409
410 if !(self.predicate)(item) {
411 if i >= self.m {
412 return Ok((
413 input.take_from(index),
414 OM::Output::bind(|| input.take(index)),
415 ));
416 } else {
417 return Err(Err::Error(OM::Error::bind(|| {
418 Error::from_error_kind(input, ErrorKind::TakeWhileMN)
419 })));
420 }
421 }
422 count += 1;
423 }
424
425 let input_len = input.input_len();
426 if OM::Incomplete::is_streaming() {
427 let needed = if self.m > input_len {
428 self.m - input_len
429 } else {
430 1
431 };
432 Err(Err::Incomplete(Needed::new(needed)))
433 } else if count >= self.m {
434 Ok((
435 input.take_from(input_len),
436 OM::Output::bind(|| input.take(input_len)),
437 ))
438 } else {
439 Err(Err::Error(OM::Error::bind(|| {
440 Error::from_error_kind(input, ErrorKind::TakeWhileMN)
441 })))
442 }
443 }
444}
445
446#[allow(clippy::redundant_closure)]
465pub fn take_till<F, I, Error: ParseError<I>>(cond: F) -> impl Parser<I, Output = I, Error = Error>
466where
467 I: Input,
468 F: Fn(<I as Input>::Item) -> bool,
469{
470 SplitPosition {
471 predicate: cond,
472 error: PhantomData,
473 }
474}
475
476#[allow(clippy::redundant_closure)]
499pub fn take_till1<F, I, Error: ParseError<I>>(cond: F) -> impl Parser<I, Output = I, Error = Error>
500where
501 I: Input,
502 F: Fn(<I as Input>::Item) -> bool,
503{
504 SplitPosition1 {
505 e: ErrorKind::TakeTill1,
506 predicate: cond,
507 error: PhantomData,
508 }
509}
510
511pub fn take<C, I, Error: ParseError<I>>(count: C) -> impl Parser<I, Output = I, Error = Error>
535where
536 I: Input,
537 C: ToUsize,
538{
539 Take {
540 length: count.to_usize(),
541 e: PhantomData,
542 }
543}
544
545pub struct Take<E> {
547 length: usize,
548 e: PhantomData<E>,
549}
550
551impl<I, Error: ParseError<I>> Parser<I> for Take<Error>
552where
553 I: Input,
554{
555 type Output = I;
556 type Error = Error;
557
558 fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> {
559 match i.slice_index(self.length) {
560 Err(needed) => {
561 if OM::Incomplete::is_streaming() {
562 Err(Err::Incomplete(needed))
563 } else {
564 Err(Err::Error(OM::Error::bind(|| {
565 let e: ErrorKind = ErrorKind::Eof;
566 Error::from_error_kind(i, e)
567 })))
568 }
569 }
570 Ok(index) => Ok((i.take_from(index), OM::Output::bind(|| i.take(index)))),
571 }
572 }
573}
574
575pub fn take_until<T, I, Error: ParseError<I>>(tag: T) -> impl Parser<I, Output = I, Error = Error>
597where
598 I: Input + FindSubstring<T>,
599 T: Clone,
600{
601 TakeUntil {
602 tag,
603 e: PhantomData,
604 }
605}
606
607pub struct TakeUntil<T, E> {
609 tag: T,
610 e: PhantomData<E>,
611}
612
613impl<I, T, Error: ParseError<I>> Parser<I> for TakeUntil<T, Error>
614where
615 I: Input + FindSubstring<T>,
616 T: Clone,
617{
618 type Output = I;
619 type Error = Error;
620
621 fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> {
622 match i.find_substring(self.tag.clone()) {
623 None => {
624 if OM::Incomplete::is_streaming() {
625 Err(Err::Incomplete(Needed::Unknown))
626 } else {
627 Err(Err::Error(OM::Error::bind(|| {
628 let e: ErrorKind = ErrorKind::TakeUntil;
629 Error::from_error_kind(i, e)
630 })))
631 }
632 }
633 Some(index) => Ok((i.take_from(index), OM::Output::bind(|| i.take(index)))),
634 }
635 }
636}
637
638pub fn take_until1<T, I, Error: ParseError<I>>(tag: T) -> impl Parser<I, Output = I, Error = Error>
661where
662 I: Input + FindSubstring<T>,
663 T: Clone,
664{
665 TakeUntil1 {
666 tag,
667 e: PhantomData,
668 }
669}
670
671pub struct TakeUntil1<T, E> {
673 tag: T,
674 e: PhantomData<E>,
675}
676
677impl<I, T, Error: ParseError<I>> Parser<I> for TakeUntil1<T, Error>
678where
679 I: Input + FindSubstring<T>,
680 T: Clone,
681{
682 type Output = I;
683 type Error = Error;
684
685 fn process<OM: OutputMode>(&mut self, i: I) -> crate::PResult<OM, I, Self::Output, Self::Error> {
686 match i.find_substring(self.tag.clone()) {
687 None => {
688 if OM::Incomplete::is_streaming() {
689 Err(Err::Incomplete(Needed::Unknown))
690 } else {
691 Err(Err::Error(OM::Error::bind(|| {
692 let e: ErrorKind = ErrorKind::TakeUntil;
693 Error::from_error_kind(i, e)
694 })))
695 }
696 }
697 Some(0) => Err(Err::Error(OM::Error::bind(|| {
698 Error::from_error_kind(i, ErrorKind::TakeUntil)
699 }))),
700
701 Some(index) => Ok((i.take_from(index), OM::Output::bind(|| i.take(index)))),
702 }
703 }
704}
705
706pub fn escaped<I, Error, F, G>(
727 normal: F,
728 control_char: char,
729 escapable: G,
730) -> impl Parser<I, Output = I, Error = Error>
731where
732 I: Input + Clone + crate::traits::Offset,
733 <I as Input>::Item: crate::traits::AsChar,
734 F: Parser<I, Error = Error>,
735 G: Parser<I, Error = Error>,
736 Error: ParseError<I>,
737{
738 Escaped {
739 normal,
740 escapable,
741 control_char,
742 e: PhantomData,
743 }
744}
745
746pub struct Escaped<F, G, E> {
748 normal: F,
749 escapable: G,
750 control_char: char,
751 e: PhantomData<E>,
752}
753
754impl<I, Error: ParseError<I>, F, G> Parser<I> for Escaped<F, G, Error>
755where
756 I: Input + Clone + crate::traits::Offset,
757 <I as Input>::Item: crate::traits::AsChar,
758 F: Parser<I, Error = Error>,
759 G: Parser<I, Error = Error>,
760 Error: ParseError<I>,
761{
762 type Output = I;
763 type Error = Error;
764
765 fn process<OM: OutputMode>(
766 &mut self,
767 input: I,
768 ) -> crate::PResult<OM, I, Self::Output, Self::Error> {
769 let mut i = input.clone();
770
771 while i.input_len() > 0 {
772 let current_len = i.input_len();
773
774 match self
775 .normal
776 .process::<OutputM<Check, Check, OM::Incomplete>>(i.clone())
777 {
778 Ok((i2, _)) => {
779 if i2.input_len() == 0 {
780 if OM::Incomplete::is_streaming() {
781 return Err(Err::Incomplete(Needed::Unknown));
782 } else {
783 let index = input.input_len();
784 return Ok((
785 input.take_from(index),
786 OM::Output::bind(|| input.take(index)),
787 ));
788 }
789 } else if i2.input_len() == current_len {
790 let index = input.offset(&i2);
791 return Ok((
792 input.take_from(index),
793 OM::Output::bind(|| input.take(index)),
794 ));
795 } else {
796 i = i2;
797 }
798 }
799 Err(Err::Error(_)) => {
800 if i.iter_elements().next().unwrap().as_char() == self.control_char {
802 let next = self.control_char.len_utf8();
803 if next >= i.input_len() {
804 if OM::Incomplete::is_streaming() {
805 return Err(Err::Incomplete(Needed::new(1)));
806 } else {
807 return Err(Err::Error(OM::Error::bind(|| {
808 Error::from_error_kind(input, ErrorKind::Escaped)
809 })));
810 }
811 } else {
812 match self
813 .escapable
814 .process::<OutputM<Check, OM::Error, OM::Incomplete>>(i.take_from(next))
815 {
816 Ok((i2, _)) => {
817 if i2.input_len() == 0 {
818 if OM::Incomplete::is_streaming() {
819 return Err(Err::Incomplete(Needed::Unknown));
820 } else {
821 let index = input.input_len();
822 return Ok((
823 input.take_from(index),
824 OM::Output::bind(|| input.take(index)),
825 ));
826 }
827 } else {
828 i = i2;
829 }
830 }
831 Err(e) => return Err(e),
832 }
833 }
834 } else {
835 let index = input.offset(&i);
836 if index == 0 {
837 return Err(Err::Error(OM::Error::bind(|| {
838 Error::from_error_kind(input, ErrorKind::Escaped)
839 })));
840 } else {
841 return Ok((
842 input.take_from(index),
843 OM::Output::bind(|| input.take(index)),
844 ));
845 }
846 }
847 }
848 Err(Err::Failure(e)) => {
849 return Err(Err::Failure(e));
850 }
851 Err(Err::Incomplete(i)) => {
852 return Err(Err::Incomplete(i));
853 }
854 }
855 }
856
857 if OM::Incomplete::is_streaming() {
858 Err(Err::Incomplete(Needed::Unknown))
859 } else {
860 let index = input.input_len();
861 Ok((
862 input.take_from(index),
863 OM::Output::bind(|| input.take(index)),
864 ))
865 }
866 }
867}
868
869#[cfg(feature = "alloc")]
900#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
901pub fn escaped_transform<I, Error, F, G, ExtendItem, Output>(
902 normal: F,
903 control_char: char,
904 transform: G,
905) -> impl Parser<I, Output = Output, Error = Error>
906where
907 I: Clone + crate::traits::Offset + Input,
908 I: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
909 <F as Parser<I>>::Output: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
910 <G as Parser<I>>::Output: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
911 <I as Input>::Item: crate::traits::AsChar,
912 F: Parser<I, Error = Error>,
913 G: Parser<I, Error = Error>,
914 Error: ParseError<I>,
915{
916 EscapedTransform {
917 normal,
918 control_char,
919 transform,
920 e: PhantomData,
921 extend: PhantomData,
922 o: PhantomData,
923 }
924}
925
926pub struct EscapedTransform<F, G, E, ExtendItem, Output> {
928 normal: F,
929 transform: G,
930 control_char: char,
931 e: PhantomData<E>,
932 extend: PhantomData<ExtendItem>,
933 o: PhantomData<Output>,
934}
935
936impl<I, Error: ParseError<I>, F, G, ExtendItem, Output> Parser<I>
937 for EscapedTransform<F, G, Error, ExtendItem, Output>
938where
939 I: Clone + crate::traits::Offset + Input,
940 I: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
941 <F as Parser<I>>::Output: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
942 <G as Parser<I>>::Output: crate::traits::ExtendInto<Item = ExtendItem, Extender = Output>,
943 <I as Input>::Item: crate::traits::AsChar,
944 F: Parser<I, Error = Error>,
945 G: Parser<I, Error = Error>,
946 Error: ParseError<I>,
947{
948 type Output = Output;
949 type Error = Error;
950
951 fn process<OM: OutputMode>(
952 &mut self,
953 input: I,
954 ) -> crate::PResult<OM, I, Self::Output, Self::Error> {
955 let mut index = 0;
956 let mut res = OM::Output::bind(|| input.new_builder());
957
958 while index < input.input_len() {
959 let current_len = input.input_len();
960 let remainder = input.take_from(index);
961 match self.normal.process::<OM>(remainder.clone()) {
962 Ok((i2, o)) => {
963 res = OM::Output::combine(o, res, |o, mut res| {
964 o.extend_into(&mut res);
965 res
966 });
967 if i2.input_len() == 0 {
968 if OM::Incomplete::is_streaming() {
969 return Err(Err::Incomplete(Needed::Unknown));
970 } else {
971 let index = input.input_len();
972 return Ok((input.take_from(index), res));
973 }
974 } else if i2.input_len() == current_len {
975 return Ok((remainder, res));
976 } else {
977 index = input.offset(&i2);
978 }
979 }
980 Err(Err::Error(_)) => {
981 if remainder.iter_elements().next().unwrap().as_char() == self.control_char {
983 let next = index + self.control_char.len_utf8();
984 let input_len = input.input_len();
985
986 if next >= input_len {
987 if OM::Incomplete::is_streaming() {
988 return Err(Err::Incomplete(Needed::Unknown));
989 } else {
990 return Err(Err::Error(OM::Error::bind(|| {
991 Error::from_error_kind(remainder, ErrorKind::EscapedTransform)
992 })));
993 }
994 } else {
995 match self.transform.process::<OM>(input.take_from(next)) {
996 Ok((i2, o)) => {
997 res = OM::Output::combine(o, res, |o, mut res| {
998 o.extend_into(&mut res);
999 res
1000 });
1001 if i2.input_len() == 0 {
1002 if OM::Incomplete::is_streaming() {
1003 return Err(Err::Incomplete(Needed::Unknown));
1004 } else {
1005 return Ok((input.take_from(input.input_len()), res));
1006 }
1007 } else {
1008 index = input.offset(&i2);
1009 }
1010 }
1011 Err(Err::Error(e)) => return Err(Err::Error(e)),
1012 Err(Err::Failure(e)) => {
1013 return Err(Err::Failure(e));
1014 }
1015 Err(Err::Incomplete(i)) => {
1016 return Err(Err::Incomplete(i));
1017 }
1018 }
1019 }
1020 } else {
1021 if index == 0 {
1022 return Err(Err::Error(OM::Error::bind(|| {
1023 Error::from_error_kind(remainder, ErrorKind::EscapedTransform)
1024 })));
1025 }
1026 return Ok((remainder, res));
1027 }
1028 }
1029 Err(Err::Failure(e)) => {
1030 return Err(Err::Failure(e));
1031 }
1032 Err(Err::Incomplete(i)) => {
1033 return Err(Err::Incomplete(i));
1034 }
1035 }
1036 }
1037
1038 if OM::Incomplete::is_streaming() {
1039 Err(Err::Incomplete(Needed::Unknown))
1040 } else {
1041 Ok((input.take_from(index), res))
1042 }
1043 }
1044}