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}