1#![allow(deprecated)]
4
5use crate::error::ErrorKind;
6use crate::error::ParseError;
7use crate::input::{
8 Compare, CompareResult, FindSubstring, FindToken, InputIter, InputLength, InputTake,
9 InputTakeAtPosition, IntoOutput, Slice, ToUsize,
10};
11use crate::lib::std::ops::RangeFrom;
12use crate::lib::std::result::Result::*;
13use crate::IntoOutputIResult;
14use crate::{Err, IResult, Needed, Parser};
15
16pub(crate) fn any<I, E: ParseError<I>>(input: I) -> IResult<I, <I as InputIter>::Item, E>
17where
18 I: InputIter + InputLength + Slice<RangeFrom<usize>>,
19{
20 let mut it = input.iter_indices();
21 match it.next() {
22 None => Err(Err::Incomplete(Needed::new(1))),
23 Some((_, c)) => match it.next() {
24 None => Ok((input.slice(input.input_len()..), c)),
25 Some((idx, _)) => Ok((input.slice(idx..), c)),
26 },
27 }
28}
29
30#[deprecated(
51 since = "8.0.0",
52 note = "Replaced with `nom8::bytes::tag` with input wrapped in `nom8::input::Streaming`"
53)]
54pub fn tag<T, Input, Error: ParseError<Input>>(
55 tag: T,
56) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
57where
58 Input: InputTake + InputLength + Compare<T>,
59 Input: IntoOutput,
60 T: InputLength + Clone,
61{
62 move |i: Input| tag_internal(i, tag.clone())
63}
64
65pub(crate) fn tag_internal<T, Input, Error: ParseError<Input>>(
66 i: Input,
67 t: T,
68) -> IResult<Input, <Input as IntoOutput>::Output, Error>
69where
70 Input: InputTake + InputLength + Compare<T>,
71 Input: IntoOutput,
72 T: InputLength,
73{
74 let tag_len = t.input_len();
75
76 let res: IResult<_, _, Error> = match i.compare(t) {
77 CompareResult::Ok => Ok(i.take_split(tag_len)),
78 CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(tag_len - i.input_len()))),
79 CompareResult::Error => {
80 let e: ErrorKind = ErrorKind::Tag;
81 Err(Err::Error(Error::from_error_kind(i, e)))
82 }
83 };
84 res.into_output()
85}
86
87#[deprecated(
109 since = "8.0.0",
110 note = "Replaced with `nom8::bytes::tag_no_case` with input wrapped in `nom8::input::Streaming`"
111)]
112pub fn tag_no_case<T, Input, Error: ParseError<Input>>(
113 tag: T,
114) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
115where
116 Input: InputTake + InputLength + Compare<T>,
117 Input: IntoOutput,
118 T: InputLength + Clone,
119{
120 move |i: Input| tag_no_case_internal(i, tag.clone())
121}
122
123pub(crate) fn tag_no_case_internal<T, Input, Error: ParseError<Input>>(
124 i: Input,
125 t: T,
126) -> IResult<Input, <Input as IntoOutput>::Output, Error>
127where
128 Input: InputTake + InputLength + Compare<T>,
129 Input: IntoOutput,
130 T: InputLength,
131{
132 let tag_len = t.input_len();
133
134 let res: IResult<_, _, Error> = match (i).compare_no_case(t) {
135 CompareResult::Ok => Ok(i.take_split(tag_len)),
136 CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(tag_len - i.input_len()))),
137 CompareResult::Error => {
138 let e: ErrorKind = ErrorKind::Tag;
139 Err(Err::Error(Error::from_error_kind(i, e)))
140 }
141 };
142 res.into_output()
143}
144
145pub(crate) fn one_of_internal<I, T, E: ParseError<I>>(
146 input: I,
147 list: &T,
148) -> IResult<I, <I as InputIter>::Item, E>
149where
150 I: Slice<RangeFrom<usize>> + InputIter + InputLength,
151 <I as InputIter>::Item: Copy,
152 T: FindToken<<I as InputIter>::Item>,
153{
154 let mut it = input.iter_indices();
155 match it.next() {
156 Some((_, c)) if list.find_token(c) => match it.next() {
157 None => Ok((input.slice(input.input_len()..), c)),
158 Some((idx, _)) => Ok((input.slice(idx..), c)),
159 },
160 Some(_) => Err(Err::Error(E::from_error_kind(input, ErrorKind::OneOf))),
161 None => Err(Err::Incomplete(Needed::new(1))),
162 }
163}
164
165pub(crate) fn none_of_internal<I, T, E: ParseError<I>>(
166 input: I,
167 list: &T,
168) -> IResult<I, <I as InputIter>::Item, E>
169where
170 I: Slice<RangeFrom<usize>> + InputIter + InputLength,
171 <I as InputIter>::Item: Copy,
172 T: FindToken<<I as InputIter>::Item>,
173{
174 let mut it = input.iter_indices();
175 match it.next() {
176 Some((_, c)) if !list.find_token(c) => match it.next() {
177 None => Ok((input.slice(input.input_len()..), c)),
178 Some((idx, _)) => Ok((input.slice(idx..), c)),
179 },
180 Some(_) => Err(Err::Error(E::from_error_kind(input, ErrorKind::NoneOf))),
181 None => Err(Err::Incomplete(Needed::new(1))),
182 }
183}
184
185#[deprecated(
209 since = "8.0.0",
210 note = "Replaced with `nom8::bytes::take_till1` with input wrapped in `nom8::input::Streaming`"
211)]
212pub fn is_not<T, Input, Error: ParseError<Input>>(
213 arr: T,
214) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
215where
216 Input: InputTakeAtPosition,
217 Input: IntoOutput,
218 T: FindToken<<Input as InputTakeAtPosition>::Item>,
219{
220 move |i: Input| is_not_internal(i, &arr)
221}
222
223pub(crate) fn is_not_internal<T, Input, Error: ParseError<Input>>(
224 i: Input,
225 arr: &T,
226) -> IResult<Input, <Input as IntoOutput>::Output, Error>
227where
228 Input: InputTakeAtPosition,
229 Input: IntoOutput,
230 T: FindToken<<Input as InputTakeAtPosition>::Item>,
231{
232 let e: ErrorKind = ErrorKind::IsNot;
233 i.split_at_position1_streaming(|c| arr.find_token(c), e)
234 .into_output()
235}
236
237#[deprecated(
263 since = "8.0.0",
264 note = "Replaced with `nom8::bytes::take_while1` with input wrapped in `nom8::input::Streaming`"
265)]
266pub fn is_a<T, Input, Error: ParseError<Input>>(
267 arr: T,
268) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
269where
270 Input: InputTakeAtPosition,
271 Input: IntoOutput,
272 T: FindToken<<Input as InputTakeAtPosition>::Item>,
273{
274 move |i: Input| is_a_internal(i, &arr)
275}
276
277pub(crate) fn is_a_internal<T, Input, Error: ParseError<Input>>(
278 i: Input,
279 arr: &T,
280) -> IResult<Input, <Input as IntoOutput>::Output, Error>
281where
282 Input: InputTakeAtPosition,
283 Input: IntoOutput,
284 T: FindToken<<Input as InputTakeAtPosition>::Item>,
285{
286 let e: ErrorKind = ErrorKind::IsA;
287 i.split_at_position1_streaming(|c| !arr.find_token(c), e)
288 .into_output()
289}
290
291#[deprecated(
316 since = "8.0.0",
317 note = "Replaced with `nom8::bytes::take_while` with input wrapped in `nom8::input::Streaming`"
318)]
319pub fn take_while<T, Input, Error: ParseError<Input>>(
320 list: T,
321) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
322where
323 Input: InputTakeAtPosition,
324 Input: IntoOutput,
325 T: FindToken<<Input as InputTakeAtPosition>::Item>,
326{
327 move |i: Input| take_while_internal(i, &list)
328}
329
330pub(crate) fn take_while_internal<T, Input, Error: ParseError<Input>>(
331 i: Input,
332 list: &T,
333) -> IResult<Input, <Input as IntoOutput>::Output, Error>
334where
335 Input: InputTakeAtPosition,
336 Input: IntoOutput,
337 T: FindToken<<Input as InputTakeAtPosition>::Item>,
338{
339 i.split_at_position_streaming(|c| !list.find_token(c))
340 .into_output()
341}
342
343#[deprecated(
370 since = "8.0.0",
371 note = "Replaced with `nom8::bytes::take_while1` with input wrapped in `nom8::input::Streaming`"
372)]
373pub fn take_while1<T, Input, Error: ParseError<Input>>(
374 list: T,
375) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
376where
377 Input: InputTakeAtPosition,
378 Input: IntoOutput,
379 T: FindToken<<Input as InputTakeAtPosition>::Item>,
380{
381 move |i: Input| take_while1_internal(i, &list)
382}
383
384pub(crate) fn take_while1_internal<T, Input, Error: ParseError<Input>>(
385 i: Input,
386 list: &T,
387) -> IResult<Input, <Input as IntoOutput>::Output, Error>
388where
389 Input: InputTakeAtPosition,
390 Input: IntoOutput,
391 T: FindToken<<Input as InputTakeAtPosition>::Item>,
392{
393 let e: ErrorKind = ErrorKind::TakeWhile1;
394 i.split_at_position1_streaming(|c| !list.find_token(c), e)
395 .into_output()
396}
397
398#[deprecated(
426 since = "8.0.0",
427 note = "Replaced with `nom8::bytes::take_while_m_n` with input wrapped in `nom8::input::Streaming`"
428)]
429pub fn take_while_m_n<T, Input, Error: ParseError<Input>>(
430 m: usize,
431 n: usize,
432 list: T,
433) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
434where
435 Input: InputTake + InputIter + InputLength,
436 Input: IntoOutput,
437 T: FindToken<<Input as InputIter>::Item>,
438{
439 move |i: Input| take_while_m_n_internal(i, m, n, &list)
440}
441
442pub(crate) fn take_while_m_n_internal<T, Input, Error: ParseError<Input>>(
443 i: Input,
444 m: usize,
445 n: usize,
446 list: &T,
447) -> IResult<Input, <Input as IntoOutput>::Output, Error>
448where
449 Input: InputTake + InputIter + InputLength,
450 Input: IntoOutput,
451 T: FindToken<<Input as InputIter>::Item>,
452{
453 let input = i;
454
455 match input.position(|c| !list.find_token(c)) {
456 Some(idx) => {
457 if idx >= m {
458 if idx <= n {
459 let res: IResult<_, _, Error> = if let Ok(index) = input.slice_index(idx) {
460 Ok(input.take_split(index)).into_output()
461 } else {
462 Err(Err::Error(Error::from_error_kind(
463 input,
464 ErrorKind::TakeWhileMN,
465 )))
466 };
467 res
468 } else {
469 let res: IResult<_, _, Error> = if let Ok(index) = input.slice_index(n) {
470 Ok(input.take_split(index)).into_output()
471 } else {
472 Err(Err::Error(Error::from_error_kind(
473 input,
474 ErrorKind::TakeWhileMN,
475 )))
476 };
477 res
478 }
479 } else {
480 let e = ErrorKind::TakeWhileMN;
481 Err(Err::Error(Error::from_error_kind(input, e)))
482 }
483 }
484 None => {
485 let len = input.input_len();
486 if len >= n {
487 match input.slice_index(n) {
488 Ok(index) => Ok(input.take_split(index)).into_output(),
489 Err(_needed) => Err(Err::Error(Error::from_error_kind(
490 input,
491 ErrorKind::TakeWhileMN,
492 ))),
493 }
494 } else {
495 let needed = if m > len { m - len } else { 1 };
496 Err(Err::Incomplete(Needed::new(needed)))
497 }
498 }
499 }
500}
501
502#[deprecated(
528 since = "8.0.0",
529 note = "Replaced with `nom8::bytes::take_till` with input wrapped in `nom8::input::Streaming`"
530)]
531pub fn take_till<T, Input, Error: ParseError<Input>>(
532 list: T,
533) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
534where
535 Input: InputTakeAtPosition,
536 Input: IntoOutput,
537 T: FindToken<<Input as InputTakeAtPosition>::Item>,
538{
539 move |i: Input| take_till_internal(i, &list)
540}
541
542pub(crate) fn take_till_internal<T, Input, Error: ParseError<Input>>(
543 i: Input,
544 list: &T,
545) -> IResult<Input, <Input as IntoOutput>::Output, Error>
546where
547 Input: InputTakeAtPosition,
548 Input: IntoOutput,
549 T: FindToken<<Input as InputTakeAtPosition>::Item>,
550{
551 i.split_at_position_streaming(|c| list.find_token(c))
552 .into_output()
553}
554
555#[deprecated(
580 since = "8.0.0",
581 note = "Replaced with `nom8::bytes::take_till1` with input wrapped in `nom8::input::Streaming`"
582)]
583pub fn take_till1<T, Input, Error: ParseError<Input>>(
584 list: T,
585) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
586where
587 Input: InputTakeAtPosition,
588 Input: IntoOutput,
589 T: FindToken<<Input as InputTakeAtPosition>::Item>,
590{
591 move |i: Input| take_till1_internal(i, &list)
592}
593
594pub(crate) fn take_till1_internal<T, Input, Error: ParseError<Input>>(
595 i: Input,
596 list: &T,
597) -> IResult<Input, <Input as IntoOutput>::Output, Error>
598where
599 Input: InputTakeAtPosition,
600 Input: IntoOutput,
601 T: FindToken<<Input as InputTakeAtPosition>::Item>,
602{
603 let e: ErrorKind = ErrorKind::TakeTill1;
604 i.split_at_position1_streaming(|c| list.find_token(c), e)
605 .into_output()
606}
607
608#[deprecated(
634 since = "8.0.0",
635 note = "Replaced with `nom8::bytes::take` with input wrapped in `nom8::input::Streaming`"
636)]
637pub fn take<C, Input, Error: ParseError<Input>>(
638 count: C,
639) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
640where
641 Input: InputIter + InputTake + InputLength,
642 Input: IntoOutput,
643 C: ToUsize,
644{
645 let c = count.to_usize();
646 move |i: Input| take_internal(i, c)
647}
648
649pub(crate) fn take_internal<Input, Error: ParseError<Input>>(
650 i: Input,
651 c: usize,
652) -> IResult<Input, <Input as IntoOutput>::Output, Error>
653where
654 Input: InputIter + InputTake + InputLength,
655 Input: IntoOutput,
656{
657 match i.slice_index(c) {
658 Err(i) => Err(Err::Incomplete(i)),
659 Ok(index) => Ok(i.take_split(index)).into_output(),
660 }
661}
662
663#[deprecated(
687 since = "8.0.0",
688 note = "Replaced with `nom8::bytes::take_until` with input wrapped in `nom8::input::Streaming`"
689)]
690pub fn take_until<T, Input, Error: ParseError<Input>>(
691 tag: T,
692) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
693where
694 Input: InputTake + InputLength + FindSubstring<T>,
695 Input: IntoOutput,
696 T: Clone,
697{
698 move |i: Input| take_until_internal(i, tag.clone())
699}
700
701pub(crate) fn take_until_internal<T, Input, Error: ParseError<Input>>(
702 i: Input,
703 t: T,
704) -> IResult<Input, <Input as IntoOutput>::Output, Error>
705where
706 Input: InputTake + InputLength + FindSubstring<T>,
707 Input: IntoOutput,
708{
709 let res: IResult<_, _, Error> = match i.find_substring(t) {
710 None => Err(Err::Incomplete(Needed::Unknown)),
711 Some(index) => Ok(i.take_split(index)),
712 };
713 res.into_output()
714}
715
716#[deprecated(
741 since = "8.0.0",
742 note = "Replaced with `nom8::bytes::take_until1` with input wrapped in `nom8::input::Streaming`"
743)]
744pub fn take_until1<T, Input, Error: ParseError<Input>>(
745 tag: T,
746) -> impl Fn(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
747where
748 Input: InputTake + InputLength + FindSubstring<T>,
749 Input: IntoOutput,
750 T: Clone,
751{
752 move |i: Input| take_until1_internal(i, tag.clone())
753}
754
755pub(crate) fn take_until1_internal<T, Input, Error: ParseError<Input>>(
756 i: Input,
757 t: T,
758) -> IResult<Input, <Input as IntoOutput>::Output, Error>
759where
760 Input: InputTake + InputLength + FindSubstring<T>,
761 Input: IntoOutput,
762{
763 let res: IResult<_, _, Error> = match i.find_substring(t) {
764 None => Err(Err::Incomplete(Needed::Unknown)),
765 Some(0) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::TakeUntil))),
766 Some(index) => Ok(i.take_split(index)),
767 };
768 res.into_output()
769}
770
771#[deprecated(
794 since = "8.0.0",
795 note = "Replaced with `nom8::bytes::escaped` with input wrapped in `nom8::input::Streaming`"
796)]
797pub fn escaped<Input, Error, F, G, O1, O2>(
798 mut normal: F,
799 control_char: char,
800 mut escapable: G,
801) -> impl FnMut(Input) -> IResult<Input, <Input as IntoOutput>::Output, Error>
802where
803 Input: Clone
804 + crate::input::Offset
805 + InputLength
806 + InputTake
807 + InputTakeAtPosition
808 + Slice<RangeFrom<usize>>
809 + InputIter,
810 Input: IntoOutput,
811 <Input as InputIter>::Item: crate::input::AsChar,
812 F: Parser<Input, O1, Error>,
813 G: Parser<Input, O2, Error>,
814 Error: ParseError<Input>,
815{
816 move |input: Input| escaped_internal(input, &mut normal, control_char, &mut escapable)
817}
818
819pub(crate) fn escaped_internal<Input, Error, F, G, O1, O2>(
820 input: Input,
821 normal: &mut F,
822 control_char: char,
823 escapable: &mut G,
824) -> IResult<Input, <Input as IntoOutput>::Output, Error>
825where
826 Input: Clone
827 + crate::input::Offset
828 + InputLength
829 + InputTake
830 + InputTakeAtPosition
831 + Slice<RangeFrom<usize>>
832 + InputIter,
833 Input: IntoOutput,
834 <Input as InputIter>::Item: crate::input::AsChar,
835 F: Parser<Input, O1, Error>,
836 G: Parser<Input, O2, Error>,
837 Error: ParseError<Input>,
838{
839 use crate::input::AsChar;
840
841 let mut i = input.clone();
842
843 while i.input_len() > 0 {
844 let current_len = i.input_len();
845
846 match normal.parse(i.clone()) {
847 Ok((i2, _)) => {
848 if i2.input_len() == 0 {
849 return Err(Err::Incomplete(Needed::Unknown));
850 } else if i2.input_len() == current_len {
851 let index = input.offset(&i2);
852 return Ok(input.take_split(index)).into_output();
853 } else {
854 i = i2;
855 }
856 }
857 Err(Err::Error(_)) => {
858 if i.iter_elements().next().unwrap().as_char() == control_char {
860 let next = control_char.len_utf8();
861 if next >= i.input_len() {
862 return Err(Err::Incomplete(Needed::new(1)));
863 } else {
864 match escapable.parse(i.slice(next..)) {
865 Ok((i2, _)) => {
866 if i2.input_len() == 0 {
867 return Err(Err::Incomplete(Needed::Unknown));
868 } else {
869 i = i2;
870 }
871 }
872 Err(e) => return Err(e),
873 }
874 }
875 } else {
876 let index = input.offset(&i);
877 return Ok(input.take_split(index)).into_output();
878 }
879 }
880 Err(e) => {
881 return Err(e);
882 }
883 }
884 }
885
886 Err(Err::Incomplete(Needed::Unknown))
887}
888
889#[cfg(feature = "alloc")]
920#[deprecated(
923 since = "8.0.0",
924 note = "Replaced with `nom8::bytes::escaped_transform` with input wrapped in `nom8::input::Streaming`"
925)]
926pub fn escaped_transform<Input, Error, F, G, O1, O2, ExtendItem, Output>(
927 mut normal: F,
928 control_char: char,
929 mut transform: G,
930) -> impl FnMut(Input) -> IResult<Input, Output, Error>
931where
932 Input: Clone
933 + crate::input::Offset
934 + InputLength
935 + InputTake
936 + InputTakeAtPosition
937 + Slice<RangeFrom<usize>>
938 + InputIter,
939 Input: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
940 O1: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
941 O2: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
942 <Input as InputIter>::Item: crate::input::AsChar,
943 F: Parser<Input, O1, Error>,
944 G: Parser<Input, O2, Error>,
945 Error: ParseError<Input>,
946{
947 move |input: Input| escaped_transform_internal(input, &mut normal, control_char, &mut transform)
948}
949
950#[cfg(feature = "alloc")]
951pub(crate) fn escaped_transform_internal<Input, Error, F, G, O1, O2, ExtendItem, Output>(
952 input: Input,
953 normal: &mut F,
954 control_char: char,
955 transform: &mut G,
956) -> IResult<Input, Output, Error>
957where
958 Input: Clone
959 + crate::input::Offset
960 + InputLength
961 + InputTake
962 + InputTakeAtPosition
963 + Slice<RangeFrom<usize>>
964 + InputIter,
965 Input: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
966 O1: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
967 O2: crate::input::ExtendInto<Item = ExtendItem, Extender = Output>,
968 <Input as InputIter>::Item: crate::input::AsChar,
969 F: Parser<Input, O1, Error>,
970 G: Parser<Input, O2, Error>,
971 Error: ParseError<Input>,
972{
973 use crate::input::AsChar;
974
975 let mut index = 0;
976 let mut res = input.new_builder();
977
978 let i = input.clone();
979
980 while index < i.input_len() {
981 let current_len = i.input_len();
982 let remainder = i.slice(index..);
983 match normal.parse(remainder.clone()) {
984 Ok((i2, o)) => {
985 o.extend_into(&mut res);
986 if i2.input_len() == 0 {
987 return Err(Err::Incomplete(Needed::Unknown));
988 } else if i2.input_len() == current_len {
989 return Ok((remainder, res));
990 } else {
991 index = input.offset(&i2);
992 }
993 }
994 Err(Err::Error(_)) => {
995 if remainder.iter_elements().next().unwrap().as_char() == control_char {
997 let next = index + control_char.len_utf8();
998 let input_len = input.input_len();
999
1000 if next >= input_len {
1001 return Err(Err::Incomplete(Needed::Unknown));
1002 } else {
1003 match transform.parse(i.slice(next..)) {
1004 Ok((i2, o)) => {
1005 o.extend_into(&mut res);
1006 if i2.input_len() == 0 {
1007 return Err(Err::Incomplete(Needed::Unknown));
1008 } else {
1009 index = input.offset(&i2);
1010 }
1011 }
1012 Err(e) => return Err(e),
1013 }
1014 }
1015 } else {
1016 return Ok((remainder, res));
1017 }
1018 }
1019 Err(e) => return Err(e),
1020 }
1021 }
1022 Err(Err::Incomplete(Needed::Unknown))
1023}
1024
1025#[cfg(test)]
1026mod tests {
1027 use crate::character::streaming::{
1028 alpha1 as alpha, alphanumeric1 as alphanumeric, digit1 as digit, hex_digit1 as hex_digit,
1029 multispace1 as multispace, oct_digit1 as oct_digit, space1 as space,
1030 };
1031 use crate::error::ErrorKind;
1032 use crate::input::AsChar;
1033 use crate::{Err, IResult, Needed};
1034
1035 #[test]
1036 fn is_a() {
1037 use crate::bytes::streaming::is_a;
1038
1039 fn a_or_b(i: &[u8]) -> IResult<&[u8], &[u8]> {
1040 is_a("ab")(i)
1041 }
1042
1043 let a = &b"abcd"[..];
1044 assert_eq!(a_or_b(a), Ok((&b"cd"[..], &b"ab"[..])));
1045
1046 let b = &b"bcde"[..];
1047 assert_eq!(a_or_b(b), Ok((&b"cde"[..], &b"b"[..])));
1048
1049 let c = &b"cdef"[..];
1050 assert_eq!(
1051 a_or_b(c),
1052 Err(Err::Error(error_position!(c, ErrorKind::IsA)))
1053 );
1054
1055 let d = &b"bacdef"[..];
1056 assert_eq!(a_or_b(d), Ok((&b"cdef"[..], &b"ba"[..])));
1057 }
1058
1059 #[test]
1060 fn is_not() {
1061 use crate::bytes::streaming::is_not;
1062
1063 fn a_or_b(i: &[u8]) -> IResult<&[u8], &[u8]> {
1064 is_not("ab")(i)
1065 }
1066
1067 let a = &b"cdab"[..];
1068 assert_eq!(a_or_b(a), Ok((&b"ab"[..], &b"cd"[..])));
1069
1070 let b = &b"cbde"[..];
1071 assert_eq!(a_or_b(b), Ok((&b"bde"[..], &b"c"[..])));
1072
1073 let c = &b"abab"[..];
1074 assert_eq!(
1075 a_or_b(c),
1076 Err(Err::Error(error_position!(c, ErrorKind::IsNot)))
1077 );
1078
1079 let d = &b"cdefba"[..];
1080 assert_eq!(a_or_b(d), Ok((&b"ba"[..], &b"cdef"[..])));
1081
1082 let e = &b"e"[..];
1083 assert_eq!(a_or_b(e), Err(Err::Incomplete(Needed::new(1))));
1084 }
1085
1086 #[test]
1087 fn take_until_incomplete() {
1088 use crate::bytes::streaming::take_until;
1089 fn y(i: &[u8]) -> IResult<&[u8], &[u8]> {
1090 take_until("end")(i)
1091 }
1092 assert_eq!(y(&b"nd"[..]), Err(Err::Incomplete(Needed::Unknown)));
1093 assert_eq!(y(&b"123"[..]), Err(Err::Incomplete(Needed::Unknown)));
1094 assert_eq!(y(&b"123en"[..]), Err(Err::Incomplete(Needed::Unknown)));
1095 }
1096
1097 #[test]
1098 fn take_until_incomplete_s() {
1099 use crate::bytes::streaming::take_until;
1100 fn ys(i: &str) -> IResult<&str, &str> {
1101 take_until("end")(i)
1102 }
1103 assert_eq!(ys("123en"), Err(Err::Incomplete(Needed::Unknown)));
1104 }
1105
1106 #[test]
1107 fn recognize() {
1108 use crate::bytes::streaming::{tag, take};
1109 use crate::combinator::recognize;
1110 use crate::sequence::delimited;
1111
1112 fn x(i: &[u8]) -> IResult<&[u8], &[u8]> {
1113 recognize(delimited(tag("<!--"), take(5_usize), tag("-->")))(i)
1114 }
1115 let r = x(&b"<!-- abc --> aaa"[..]);
1116 assert_eq!(r, Ok((&b" aaa"[..], &b"<!-- abc -->"[..])));
1117
1118 let semicolon = &b";"[..];
1119
1120 fn ya(i: &[u8]) -> IResult<&[u8], &[u8]> {
1121 recognize(alpha)(i)
1122 }
1123 let ra = ya(&b"abc;"[..]);
1124 assert_eq!(ra, Ok((semicolon, &b"abc"[..])));
1125
1126 fn yd(i: &[u8]) -> IResult<&[u8], &[u8]> {
1127 recognize(digit)(i)
1128 }
1129 let rd = yd(&b"123;"[..]);
1130 assert_eq!(rd, Ok((semicolon, &b"123"[..])));
1131
1132 fn yhd(i: &[u8]) -> IResult<&[u8], &[u8]> {
1133 recognize(hex_digit)(i)
1134 }
1135 let rhd = yhd(&b"123abcDEF;"[..]);
1136 assert_eq!(rhd, Ok((semicolon, &b"123abcDEF"[..])));
1137
1138 fn yod(i: &[u8]) -> IResult<&[u8], &[u8]> {
1139 recognize(oct_digit)(i)
1140 }
1141 let rod = yod(&b"1234567;"[..]);
1142 assert_eq!(rod, Ok((semicolon, &b"1234567"[..])));
1143
1144 fn yan(i: &[u8]) -> IResult<&[u8], &[u8]> {
1145 recognize(alphanumeric)(i)
1146 }
1147 let ran = yan(&b"123abc;"[..]);
1148 assert_eq!(ran, Ok((semicolon, &b"123abc"[..])));
1149
1150 fn ys(i: &[u8]) -> IResult<&[u8], &[u8]> {
1151 recognize(space)(i)
1152 }
1153 let rs = ys(&b" \t;"[..]);
1154 assert_eq!(rs, Ok((semicolon, &b" \t"[..])));
1155
1156 fn yms(i: &[u8]) -> IResult<&[u8], &[u8]> {
1157 recognize(multispace)(i)
1158 }
1159 let rms = yms(&b" \t\r\n;"[..]);
1160 assert_eq!(rms, Ok((semicolon, &b" \t\r\n"[..])));
1161 }
1162
1163 #[test]
1164 fn take_while() {
1165 use crate::bytes::streaming::take_while;
1166
1167 fn f(i: &[u8]) -> IResult<&[u8], &[u8]> {
1168 take_while(AsChar::is_alpha)(i)
1169 }
1170 let a = b"";
1171 let b = b"abcd";
1172 let c = b"abcd123";
1173 let d = b"123";
1174
1175 assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
1176 assert_eq!(f(&b[..]), Err(Err::Incomplete(Needed::new(1))));
1177 assert_eq!(f(&c[..]), Ok((&d[..], &b[..])));
1178 assert_eq!(f(&d[..]), Ok((&d[..], &a[..])));
1179 }
1180
1181 #[test]
1182 fn take_while1() {
1183 use crate::bytes::streaming::take_while1;
1184
1185 fn f(i: &[u8]) -> IResult<&[u8], &[u8]> {
1186 take_while1(AsChar::is_alpha)(i)
1187 }
1188 let a = b"";
1189 let b = b"abcd";
1190 let c = b"abcd123";
1191 let d = b"123";
1192
1193 assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
1194 assert_eq!(f(&b[..]), Err(Err::Incomplete(Needed::new(1))));
1195 assert_eq!(f(&c[..]), Ok((&b"123"[..], &b[..])));
1196 assert_eq!(
1197 f(&d[..]),
1198 Err(Err::Error(error_position!(&d[..], ErrorKind::TakeWhile1)))
1199 );
1200 }
1201
1202 #[test]
1203 fn take_while_m_n() {
1204 use crate::bytes::streaming::take_while_m_n;
1205
1206 fn x(i: &[u8]) -> IResult<&[u8], &[u8]> {
1207 take_while_m_n(2, 4, AsChar::is_alpha)(i)
1208 }
1209 let a = b"";
1210 let b = b"a";
1211 let c = b"abc";
1212 let d = b"abc123";
1213 let e = b"abcde";
1214 let f = b"123";
1215
1216 assert_eq!(x(&a[..]), Err(Err::Incomplete(Needed::new(2))));
1217 assert_eq!(x(&b[..]), Err(Err::Incomplete(Needed::new(1))));
1218 assert_eq!(x(&c[..]), Err(Err::Incomplete(Needed::new(1))));
1219 assert_eq!(x(&d[..]), Ok((&b"123"[..], &c[..])));
1220 assert_eq!(x(&e[..]), Ok((&b"e"[..], &b"abcd"[..])));
1221 assert_eq!(
1222 x(&f[..]),
1223 Err(Err::Error(error_position!(&f[..], ErrorKind::TakeWhileMN)))
1224 );
1225 }
1226
1227 #[test]
1228 fn take_till() {
1229 use crate::bytes::streaming::take_till;
1230
1231 fn f(i: &[u8]) -> IResult<&[u8], &[u8]> {
1232 take_till(AsChar::is_alpha)(i)
1233 }
1234 let a = b"";
1235 let b = b"abcd";
1236 let c = b"123abcd";
1237 let d = b"123";
1238
1239 assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
1240 assert_eq!(f(&b[..]), Ok((&b"abcd"[..], &b""[..])));
1241 assert_eq!(f(&c[..]), Ok((&b"abcd"[..], &b"123"[..])));
1242 assert_eq!(f(&d[..]), Err(Err::Incomplete(Needed::new(1))));
1243 }
1244
1245 #[test]
1246 fn take_till1() {
1247 use crate::bytes::streaming::take_till1;
1248
1249 fn f(i: &[u8]) -> IResult<&[u8], &[u8]> {
1250 take_till1(AsChar::is_alpha)(i)
1251 }
1252 let a = b"";
1253 let b = b"abcd";
1254 let c = b"123abcd";
1255 let d = b"123";
1256
1257 assert_eq!(f(&a[..]), Err(Err::Incomplete(Needed::new(1))));
1258 assert_eq!(
1259 f(&b[..]),
1260 Err(Err::Error(error_position!(&b[..], ErrorKind::TakeTill1)))
1261 );
1262 assert_eq!(f(&c[..]), Ok((&b"abcd"[..], &b"123"[..])));
1263 assert_eq!(f(&d[..]), Err(Err::Incomplete(Needed::new(1))));
1264 }
1265
1266 #[test]
1267 fn take_while_utf8() {
1268 use crate::bytes::streaming::take_while;
1269
1270 fn f(i: &str) -> IResult<&str, &str> {
1271 take_while(|c| c != '點')(i)
1272 }
1273
1274 assert_eq!(f(""), Err(Err::Incomplete(Needed::new(1))));
1275 assert_eq!(f("abcd"), Err(Err::Incomplete(Needed::new(1))));
1276 assert_eq!(f("abcd點"), Ok(("點", "abcd")));
1277 assert_eq!(f("abcd點a"), Ok(("點a", "abcd")));
1278
1279 fn g(i: &str) -> IResult<&str, &str> {
1280 take_while(|c| c == '點')(i)
1281 }
1282
1283 assert_eq!(g(""), Err(Err::Incomplete(Needed::new(1))));
1284 assert_eq!(g("點abcd"), Ok(("abcd", "點")));
1285 assert_eq!(g("點點點a"), Ok(("a", "點點點")));
1286 }
1287
1288 #[test]
1289 fn take_till_utf8() {
1290 use crate::bytes::streaming::take_till;
1291
1292 fn f(i: &str) -> IResult<&str, &str> {
1293 take_till(|c| c == '點')(i)
1294 }
1295
1296 assert_eq!(f(""), Err(Err::Incomplete(Needed::new(1))));
1297 assert_eq!(f("abcd"), Err(Err::Incomplete(Needed::new(1))));
1298 assert_eq!(f("abcd點"), Ok(("點", "abcd")));
1299 assert_eq!(f("abcd點a"), Ok(("點a", "abcd")));
1300
1301 fn g(i: &str) -> IResult<&str, &str> {
1302 take_till(|c| c != '點')(i)
1303 }
1304
1305 assert_eq!(g(""), Err(Err::Incomplete(Needed::new(1))));
1306 assert_eq!(g("點abcd"), Ok(("abcd", "點")));
1307 assert_eq!(g("點點點a"), Ok(("a", "點點點")));
1308 }
1309
1310 #[test]
1311 fn take_utf8() {
1312 use crate::bytes::streaming::{take, take_while};
1313
1314 fn f(i: &str) -> IResult<&str, &str> {
1315 take(3_usize)(i)
1316 }
1317
1318 assert_eq!(f(""), Err(Err::Incomplete(Needed::Unknown)));
1319 assert_eq!(f("ab"), Err(Err::Incomplete(Needed::Unknown)));
1320 assert_eq!(f("點"), Err(Err::Incomplete(Needed::Unknown)));
1321 assert_eq!(f("ab點cd"), Ok(("cd", "ab點")));
1322 assert_eq!(f("a點bcd"), Ok(("cd", "a點b")));
1323 assert_eq!(f("a點b"), Ok(("", "a點b")));
1324
1325 fn g(i: &str) -> IResult<&str, &str> {
1326 take_while(|c| c == '點')(i)
1327 }
1328
1329 assert_eq!(g(""), Err(Err::Incomplete(Needed::new(1))));
1330 assert_eq!(g("點abcd"), Ok(("abcd", "點")));
1331 assert_eq!(g("點點點a"), Ok(("a", "點點點")));
1332 }
1333
1334 #[test]
1335 fn take_while_m_n_utf8() {
1336 use crate::bytes::streaming::take_while_m_n;
1337
1338 fn parser(i: &str) -> IResult<&str, &str> {
1339 take_while_m_n(1, 1, |c| c == 'A' || c == '😃')(i)
1340 }
1341 assert_eq!(parser("A!"), Ok(("!", "A")));
1342 assert_eq!(parser("😃!"), Ok(("!", "😃")));
1343 }
1344
1345 #[test]
1346 fn take_while_m_n_utf8_full_match() {
1347 use crate::bytes::streaming::take_while_m_n;
1348
1349 fn parser(i: &str) -> IResult<&str, &str> {
1350 take_while_m_n(1, 1, |c: char| c.is_alphabetic())(i)
1351 }
1352 assert_eq!(parser("øn"), Ok(("n", "ø")));
1353 }
1354
1355 #[test]
1356 #[cfg(feature = "std")]
1357 fn recognize_take_while() {
1358 use crate::bytes::streaming::take_while;
1359 use crate::combinator::recognize;
1360
1361 fn x(i: &[u8]) -> IResult<&[u8], &[u8]> {
1362 take_while(AsChar::is_alphanum)(i)
1363 }
1364 fn y(i: &[u8]) -> IResult<&[u8], &[u8]> {
1365 recognize(x)(i)
1366 }
1367 assert_eq!(x(&b"ab."[..]), Ok((&b"."[..], &b"ab"[..])));
1368 println!("X: {:?}", x(&b"ab"[..]));
1369 assert_eq!(y(&b"ab."[..]), Ok((&b"."[..], &b"ab"[..])));
1370 }
1371
1372 #[test]
1373 fn length_bytes() {
1374 use crate::input::Streaming;
1375 use crate::{bytes::streaming::tag, multi::length_data, number::streaming::le_u8};
1376
1377 fn x(i: Streaming<&[u8]>) -> IResult<Streaming<&[u8]>, &[u8]> {
1378 length_data(le_u8)(i)
1379 }
1380 assert_eq!(
1381 x(Streaming(b"\x02..>>")),
1382 Ok((Streaming(&b">>"[..]), &b".."[..]))
1383 );
1384 assert_eq!(
1385 x(Streaming(b"\x02..")),
1386 Ok((Streaming(&[][..]), &b".."[..]))
1387 );
1388 assert_eq!(x(Streaming(b"\x02.")), Err(Err::Incomplete(Needed::new(1))));
1389 assert_eq!(x(Streaming(b"\x02")), Err(Err::Incomplete(Needed::new(2))));
1390
1391 fn y(i: Streaming<&[u8]>) -> IResult<Streaming<&[u8]>, &[u8]> {
1392 let (i, _) = tag("magic")(i)?;
1393 length_data(le_u8)(i)
1394 }
1395 assert_eq!(
1396 y(Streaming(b"magic\x02..>>")),
1397 Ok((Streaming(&b">>"[..]), &b".."[..]))
1398 );
1399 assert_eq!(
1400 y(Streaming(b"magic\x02..")),
1401 Ok((Streaming(&[][..]), &b".."[..]))
1402 );
1403 assert_eq!(
1404 y(Streaming(b"magic\x02.")),
1405 Err(Err::Incomplete(Needed::new(1)))
1406 );
1407 assert_eq!(
1408 y(Streaming(b"magic\x02")),
1409 Err(Err::Incomplete(Needed::new(2)))
1410 );
1411 }
1412
1413 #[cfg(feature = "alloc")]
1414 #[test]
1415 fn case_insensitive() {
1416 use crate::bytes::streaming::tag_no_case;
1417
1418 fn test(i: &[u8]) -> IResult<&[u8], &[u8]> {
1419 tag_no_case("ABcd")(i)
1420 }
1421 assert_eq!(test(&b"aBCdefgh"[..]), Ok((&b"efgh"[..], &b"aBCd"[..])));
1422 assert_eq!(test(&b"abcdefgh"[..]), Ok((&b"efgh"[..], &b"abcd"[..])));
1423 assert_eq!(test(&b"ABCDefgh"[..]), Ok((&b"efgh"[..], &b"ABCD"[..])));
1424 assert_eq!(test(&b"ab"[..]), Err(Err::Incomplete(Needed::new(2))));
1425 assert_eq!(
1426 test(&b"Hello"[..]),
1427 Err(Err::Error(error_position!(&b"Hello"[..], ErrorKind::Tag)))
1428 );
1429 assert_eq!(
1430 test(&b"Hel"[..]),
1431 Err(Err::Error(error_position!(&b"Hel"[..], ErrorKind::Tag)))
1432 );
1433
1434 fn test2(i: &str) -> IResult<&str, &str> {
1435 tag_no_case("ABcd")(i)
1436 }
1437 assert_eq!(test2("aBCdefgh"), Ok(("efgh", "aBCd")));
1438 assert_eq!(test2("abcdefgh"), Ok(("efgh", "abcd")));
1439 assert_eq!(test2("ABCDefgh"), Ok(("efgh", "ABCD")));
1440 assert_eq!(test2("ab"), Err(Err::Incomplete(Needed::new(2))));
1441 assert_eq!(
1442 test2("Hello"),
1443 Err(Err::Error(error_position!(&"Hello"[..], ErrorKind::Tag)))
1444 );
1445 assert_eq!(
1446 test2("Hel"),
1447 Err(Err::Error(error_position!(&"Hel"[..], ErrorKind::Tag)))
1448 );
1449 }
1450
1451 #[test]
1452 fn tag_fixed_size_array() {
1453 use crate::bytes::streaming::tag;
1454
1455 fn test(i: &[u8]) -> IResult<&[u8], &[u8]> {
1456 tag([0x42])(i)
1457 }
1458 fn test2(i: &[u8]) -> IResult<&[u8], &[u8]> {
1459 tag(&[0x42])(i)
1460 }
1461 let input = [0x42, 0x00];
1462 assert_eq!(test(&input), Ok((&b"\x00"[..], &b"\x42"[..])));
1463 assert_eq!(test2(&input), Ok((&b"\x00"[..], &b"\x42"[..])));
1464 }
1465}