1#![allow(deprecated)]
6
7use crate::branch::alt;
8use crate::combinator::opt;
9use crate::error::ErrorKind;
10use crate::error::ParseError;
11use crate::input::{
12 AsChar, FindToken, InputIter, InputLength, InputTake, InputTakeAtPosition, IntoOutput, Slice,
13};
14use crate::input::{Compare, CompareResult};
15use crate::lib::std::ops::{Range, RangeFrom, RangeTo};
16use crate::IntoOutputIResult as _;
17use crate::{Err, IResult, Needed};
18
19#[deprecated(
37 since = "8.0.0",
38 note = "Replaced with `nom8::bytes::one_of` with input wrapped in `nom8::input::Streaming`"
39)]
40pub fn char<I, Error: ParseError<I>>(c: char) -> impl Fn(I) -> IResult<I, char, Error>
41where
42 I: Slice<RangeFrom<usize>> + InputIter + InputLength,
43 <I as InputIter>::Item: AsChar,
44{
45 move |i: I| char_internal(i, c)
46}
47
48pub(crate) fn char_internal<I, Error: ParseError<I>>(i: I, c: char) -> IResult<I, char, Error>
49where
50 I: Slice<RangeFrom<usize>> + InputIter + InputLength,
51 <I as InputIter>::Item: AsChar,
52{
53 match (i).iter_elements().next().map(|t| {
54 let b = t.as_char() == c;
55 (&c, b)
56 }) {
57 None => Err(Err::Incomplete(Needed::new(c.len() - i.input_len()))),
58 Some((_, false)) => Err(Err::Error(Error::from_char(i, c))),
59 Some((c, true)) => Ok((i.slice(c.len()..), c.as_char())),
60 }
61}
62
63#[deprecated(
81 since = "8.0.0",
82 note = "Replaced with `nom8::bytes::one_of` with input wrapped in `nom8::input::Streaming`"
83)]
84pub fn satisfy<F, I, Error: ParseError<I>>(cond: F) -> impl Fn(I) -> IResult<I, char, Error>
85where
86 I: Slice<RangeFrom<usize>> + InputIter,
87 <I as InputIter>::Item: AsChar,
88 F: Fn(char) -> bool,
89{
90 move |i: I| satisfy_internal(i, &cond)
91}
92
93pub(crate) fn satisfy_internal<F, I, Error: ParseError<I>>(
94 i: I,
95 cond: &F,
96) -> IResult<I, char, Error>
97where
98 I: Slice<RangeFrom<usize>> + InputIter,
99 <I as InputIter>::Item: AsChar,
100 F: Fn(char) -> bool,
101{
102 match (i).iter_elements().next().map(|t| {
103 let c = t.as_char();
104 let b = cond(c);
105 (c, b)
106 }) {
107 None => Err(Err::Incomplete(Needed::Unknown)),
108 Some((_, false)) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::Satisfy))),
109 Some((c, true)) => Ok((i.slice(c.len()..), c)),
110 }
111}
112
113#[deprecated(
128 since = "8.0.0",
129 note = "Replaced with `nom8::bytes::one_of` with input wrapped in `nom8::input::Streaming`"
130)]
131pub fn one_of<I, T, Error: ParseError<I>>(list: T) -> impl Fn(I) -> IResult<I, char, Error>
132where
133 I: Slice<RangeFrom<usize>> + InputIter + InputLength,
134 <I as InputIter>::Item: AsChar + Copy,
135 T: FindToken<<I as InputIter>::Item>,
136{
137 move |i: I| crate::bytes::streaming::one_of_internal(i, &list).map(|(i, c)| (i, c.as_char()))
138}
139
140#[deprecated(
155 since = "8.0.0",
156 note = "Replaced with `nom8::bytes::none_of` with input wrapped in `nom8::input::Streaming`"
157)]
158pub fn none_of<I, T, Error: ParseError<I>>(list: T) -> impl Fn(I) -> IResult<I, char, Error>
159where
160 I: Slice<RangeFrom<usize>> + InputLength + InputIter,
161 <I as InputIter>::Item: AsChar + Copy,
162 T: FindToken<<I as InputIter>::Item>,
163{
164 move |i: I| crate::bytes::streaming::none_of_internal(i, &list).map(|(i, c)| (i, c.as_char()))
165}
166
167#[deprecated(
182 since = "8.0.0",
183 note = "Replaced with `nom8::character::crlf` with input wrapped in `nom8::input::Streaming`"
184)]
185pub fn crlf<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
186where
187 T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
188 T: InputIter,
189 T: IntoOutput,
190 T: Compare<&'static str>,
191{
192 match input.compare("\r\n") {
193 CompareResult::Ok => Ok((input.slice(2..), input.slice(0..2))).into_output(),
195 CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(2))),
196 CompareResult::Error => {
197 let e: ErrorKind = ErrorKind::CrLf;
198 Err(Err::Error(E::from_error_kind(input, e)))
199 }
200 }
201}
202
203#[deprecated(
220 since = "8.0.0",
221 note = "Replaced with `nom8::character::not_line_ending` with input wrapped in `nom8::input::Streaming`"
222)]
223pub fn not_line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
224where
225 T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
226 T: InputIter + InputLength,
227 T: IntoOutput,
228 T: Compare<&'static str>,
229 <T as InputIter>::Item: AsChar,
230 <T as InputIter>::Item: AsChar,
231{
232 match input.position(|item| {
233 let c = item.as_char();
234 c == '\r' || c == '\n'
235 }) {
236 None => Err(Err::Incomplete(Needed::Unknown)),
237 Some(index) => {
238 let mut it = input.slice(index..).iter_elements();
239 let nth = it.next().unwrap().as_char();
240 if nth == '\r' {
241 let sliced = input.slice(index..);
242 let comp = sliced.compare("\r\n");
243 match comp {
244 CompareResult::Incomplete => Err(Err::Incomplete(Needed::Unknown)),
246 CompareResult::Error => {
247 let e: ErrorKind = ErrorKind::Tag;
248 Err(Err::Error(E::from_error_kind(input, e)))
249 }
250 CompareResult::Ok => Ok((input.slice(index..), input.slice(..index))).into_output(),
251 }
252 } else {
253 Ok((input.slice(index..), input.slice(..index))).into_output()
254 }
255 }
256 }
257}
258
259#[deprecated(
274 since = "8.0.0",
275 note = "Replaced with `nom8::character::line_ending` with input wrapped in `nom8::input::Streaming`"
276)]
277pub fn line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
278where
279 T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
280 T: InputIter + InputLength,
281 T: IntoOutput,
282 T: Compare<&'static str>,
283{
284 match input.compare("\n") {
285 CompareResult::Ok => Ok((input.slice(1..), input.slice(0..1))).into_output(),
286 CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(1))),
287 CompareResult::Error => {
288 match input.compare("\r\n") {
289 CompareResult::Ok => Ok((input.slice(2..), input.slice(0..2))).into_output(),
291 CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(2))),
292 CompareResult::Error => Err(Err::Error(E::from_error_kind(input, ErrorKind::CrLf))),
293 }
294 }
295 }
296}
297
298#[deprecated(
313 since = "8.0.0",
314 note = "Replaced with `nom8::character::newline` with input wrapped in `nom8::input::Streaming`"
315)]
316pub fn newline<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error>
317where
318 I: Slice<RangeFrom<usize>> + InputIter + InputLength,
319 <I as InputIter>::Item: AsChar,
320{
321 char('\n')(input)
322}
323
324#[deprecated(
339 since = "8.0.0",
340 note = "Replaced with `nom8::character::tab` with input wrapped in `nom8::input::Streaming`"
341)]
342pub fn tab<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error>
343where
344 I: Slice<RangeFrom<usize>> + InputIter + InputLength,
345 <I as InputIter>::Item: AsChar,
346{
347 char('\t')(input)
348}
349
350#[deprecated(
364 since = "8.0.0",
365 note = "Replaced with `nom8::bytes::any` with input wrapped in `nom8::input::Streaming`"
366)]
367pub fn anychar<T, E: ParseError<T>>(input: T) -> IResult<T, char, E>
368where
369 T: InputIter + InputLength + Slice<RangeFrom<usize>>,
370 <T as InputIter>::Item: AsChar,
371{
372 crate::bytes::streaming::any(input).map(|(i, c)| (i, c.as_char()))
373}
374
375#[deprecated(
391 since = "8.0.0",
392 note = "Replaced with `nom8::character::alpha0` with input wrapped in `nom8::input::Streaming`"
393)]
394pub fn alpha0<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
395where
396 T: InputTakeAtPosition,
397 T: IntoOutput,
398 <T as InputTakeAtPosition>::Item: AsChar,
399{
400 input
401 .split_at_position_streaming(|item| !item.is_alpha())
402 .into_output()
403}
404
405#[deprecated(
421 since = "8.0.0",
422 note = "Replaced with `nom8::character::alpha1` with input wrapped in `nom8::input::Streaming`"
423)]
424pub fn alpha1<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
425where
426 T: InputTakeAtPosition,
427 T: IntoOutput,
428 <T as InputTakeAtPosition>::Item: AsChar,
429{
430 input
431 .split_at_position1_streaming(|item| !item.is_alpha(), ErrorKind::Alpha)
432 .into_output()
433}
434
435#[deprecated(
451 since = "8.0.0",
452 note = "Replaced with `nom8::character::digit0` with input wrapped in `nom8::input::Streaming`"
453)]
454pub fn digit0<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
455where
456 T: InputTakeAtPosition,
457 T: IntoOutput,
458 <T as InputTakeAtPosition>::Item: AsChar,
459{
460 input
461 .split_at_position_streaming(|item| !item.is_dec_digit())
462 .into_output()
463}
464
465#[deprecated(
481 since = "8.0.0",
482 note = "Replaced with `nom8::character::digit1` with input wrapped in `nom8::input::Streaming`"
483)]
484pub fn digit1<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
485where
486 T: InputTakeAtPosition,
487 T: IntoOutput,
488 <T as InputTakeAtPosition>::Item: AsChar,
489{
490 input
491 .split_at_position1_streaming(|item| !item.is_dec_digit(), ErrorKind::Digit)
492 .into_output()
493}
494
495#[deprecated(
511 since = "8.0.0",
512 note = "Replaced with `nom8::character::hex_digit0` with input wrapped in `nom8::input::Streaming`"
513)]
514pub fn hex_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
515where
516 T: InputTakeAtPosition,
517 T: IntoOutput,
518 <T as InputTakeAtPosition>::Item: AsChar,
519{
520 input
521 .split_at_position_streaming(|item| !item.is_hex_digit())
522 .into_output()
523}
524
525#[deprecated(
541 since = "8.0.0",
542 note = "Replaced with `nom8::character::hex_digit1` with input wrapped in `nom8::input::Streaming`"
543)]
544pub fn hex_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
545where
546 T: InputTakeAtPosition,
547 T: IntoOutput,
548 <T as InputTakeAtPosition>::Item: AsChar,
549{
550 input
551 .split_at_position1_streaming(|item| !item.is_hex_digit(), ErrorKind::HexDigit)
552 .into_output()
553}
554
555#[deprecated(
571 since = "8.0.0",
572 note = "Replaced with `nom8::character::oct_digit0` with input wrapped in `nom8::input::Streaming`"
573)]
574pub fn oct_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
575where
576 T: InputTakeAtPosition,
577 T: IntoOutput,
578 <T as InputTakeAtPosition>::Item: AsChar,
579{
580 input
581 .split_at_position_streaming(|item| !item.is_oct_digit())
582 .into_output()
583}
584
585#[deprecated(
601 since = "8.0.0",
602 note = "Replaced with `nom8::character::oct_digit1` with input wrapped in `nom8::input::Streaming`"
603)]
604pub fn oct_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
605where
606 T: InputTakeAtPosition,
607 T: IntoOutput,
608 <T as InputTakeAtPosition>::Item: AsChar,
609{
610 input
611 .split_at_position1_streaming(|item| !item.is_oct_digit(), ErrorKind::OctDigit)
612 .into_output()
613}
614
615#[deprecated(
631 since = "8.0.0",
632 note = "Replaced with `nom8::character::alphanumeric0` with input wrapped in `nom8::input::Streaming`"
633)]
634pub fn alphanumeric0<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
635where
636 T: InputTakeAtPosition,
637 T: IntoOutput,
638 <T as InputTakeAtPosition>::Item: AsChar,
639{
640 input
641 .split_at_position_streaming(|item| !item.is_alphanum())
642 .into_output()
643}
644
645#[deprecated(
661 since = "8.0.0",
662 note = "Replaced with `nom8::character::alphanumeric1` with input wrapped in `nom8::input::Streaming`"
663)]
664pub fn alphanumeric1<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
665where
666 T: InputTakeAtPosition,
667 T: IntoOutput,
668 <T as InputTakeAtPosition>::Item: AsChar,
669{
670 input
671 .split_at_position1_streaming(|item| !item.is_alphanum(), ErrorKind::AlphaNumeric)
672 .into_output()
673}
674
675#[deprecated(
691 since = "8.0.0",
692 note = "Replaced with `nom8::character::space0` with input wrapped in `nom8::input::Streaming`"
693)]
694pub fn space0<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
695where
696 T: InputTakeAtPosition,
697 T: IntoOutput,
698 <T as InputTakeAtPosition>::Item: AsChar + Clone,
699{
700 input
701 .split_at_position_streaming(|item| {
702 let c = item.as_char();
703 !(c == ' ' || c == '\t')
704 })
705 .into_output()
706}
707#[deprecated(
723 since = "8.0.0",
724 note = "Replaced with `nom8::character::space1` with input wrapped in `nom8::input::Streaming`"
725)]
726pub fn space1<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
727where
728 T: InputTakeAtPosition,
729 T: IntoOutput,
730 <T as InputTakeAtPosition>::Item: AsChar + Clone,
731{
732 input
733 .split_at_position1_streaming(
734 |item| {
735 let c = item.as_char();
736 !(c == ' ' || c == '\t')
737 },
738 ErrorKind::Space,
739 )
740 .into_output()
741}
742
743#[deprecated(
759 since = "8.0.0",
760 note = "Replaced with `nom8::character::multispace0` with input wrapped in `nom8::input::Streaming`"
761)]
762pub fn multispace0<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
763where
764 T: InputTakeAtPosition,
765 T: IntoOutput,
766 <T as InputTakeAtPosition>::Item: AsChar + Clone,
767{
768 input
769 .split_at_position_streaming(|item| {
770 let c = item.as_char();
771 !(c == ' ' || c == '\t' || c == '\r' || c == '\n')
772 })
773 .into_output()
774}
775
776#[deprecated(
792 since = "8.0.0",
793 note = "Replaced with `nom8::character::multispace1` with input wrapped in `nom8::input::Streaming`"
794)]
795pub fn multispace1<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
796where
797 T: InputTakeAtPosition,
798 T: IntoOutput,
799 <T as InputTakeAtPosition>::Item: AsChar + Clone,
800{
801 input
802 .split_at_position1_streaming(
803 |item| {
804 let c = item.as_char();
805 !(c == ' ' || c == '\t' || c == '\r' || c == '\n')
806 },
807 ErrorKind::MultiSpace,
808 )
809 .into_output()
810}
811
812pub(crate) fn sign<T, E: ParseError<T>>(input: T) -> IResult<T, bool, E>
813where
814 T: Clone + InputTake + InputLength,
815 T: IntoOutput,
816 T: for<'a> Compare<&'a [u8]>,
817{
818 use crate::bytes::streaming::tag;
819 use crate::combinator::value;
820
821 let (i, opt_sign) = opt(alt((
822 value(false, tag(&b"-"[..])),
823 value(true, tag(&b"+"[..])),
824 )))(input)?;
825 let sign = opt_sign.unwrap_or(true);
826
827 Ok((i, sign))
828}
829
830#[doc(hidden)]
831macro_rules! ints {
832 ($($t:tt)+) => {
833 $(
834 pub fn $t<T, E: ParseError<T>>(input: T) -> IResult<T, $t, E>
838 where
839 T: InputIter + Slice<RangeFrom<usize>> + InputLength + InputTake + Clone,
840 T: IntoOutput,
841 <T as InputIter>::Item: AsChar,
842 T: for <'a> Compare<&'a[u8]>,
843 {
844 let (i, sign) = sign(input.clone())?;
845
846 if i.input_len() == 0 {
847 return Err(Err::Incomplete(Needed::new(1)));
848 }
849
850 let mut value: $t = 0;
851 if sign {
852 for (pos, c) in i.iter_indices() {
853 match c.as_char().to_digit(10) {
854 None => {
855 if pos == 0 {
856 return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit)));
857 } else {
858 return Ok((i.slice(pos..), value));
859 }
860 },
861 Some(d) => match value.checked_mul(10).and_then(|v| v.checked_add(d as $t)) {
862 None => return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit))),
863 Some(v) => value = v,
864 }
865 }
866 }
867 } else {
868 for (pos, c) in i.iter_indices() {
869 match c.as_char().to_digit(10) {
870 None => {
871 if pos == 0 {
872 return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit)));
873 } else {
874 return Ok((i.slice(pos..), value));
875 }
876 },
877 Some(d) => match value.checked_mul(10).and_then(|v| v.checked_sub(d as $t)) {
878 None => return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit))),
879 Some(v) => value = v,
880 }
881 }
882 }
883 }
884
885 Err(Err::Incomplete(Needed::new(1)))
886 }
887 )+
888 }
889}
890
891ints! { i8 i16 i32 i64 i128 }
892
893#[doc(hidden)]
894macro_rules! uints {
895 ($($t:tt)+) => {
896 $(
897 pub fn $t<T, E: ParseError<T>>(input: T) -> IResult<T, $t, E>
901 where
902 T: InputIter + Slice<RangeFrom<usize>> + InputLength,
903 T: IntoOutput,
904 <T as InputIter>::Item: AsChar,
905 {
906 let i = input;
907
908 if i.input_len() == 0 {
909 return Err(Err::Incomplete(Needed::new(1)));
910 }
911
912 let mut value: $t = 0;
913 for (pos, c) in i.iter_indices() {
914 match c.as_char().to_digit(10) {
915 None => {
916 if pos == 0 {
917 return Err(Err::Error(E::from_error_kind(i, ErrorKind::Digit)));
918 } else {
919 return Ok((i.slice(pos..), value));
920 }
921 },
922 Some(d) => match value.checked_mul(10).and_then(|v| v.checked_add(d as $t)) {
923 None => return Err(Err::Error(E::from_error_kind(i, ErrorKind::Digit))),
924 Some(v) => value = v,
925 }
926 }
927 }
928
929 Err(Err::Incomplete(Needed::new(1)))
930 }
931 )+
932 }
933}
934
935uints! { u8 u16 u32 u64 u128 }
936
937#[cfg(test)]
938mod tests {
939 use super::*;
940 use crate::error::ErrorKind;
941 use crate::input::ParseTo;
942 use crate::sequence::pair;
943 use crate::{Err, IResult, Needed};
944 use proptest::prelude::*;
945
946 macro_rules! assert_parse(
947 ($left: expr, $right: expr) => {
948 let res: $crate::IResult<_, _, (_, ErrorKind)> = $left;
949 assert_eq!(res, $right);
950 };
951 );
952
953 #[test]
954 fn anychar_str() {
955 use super::anychar;
956 assert_eq!(anychar::<_, (&str, ErrorKind)>("Ә"), Ok(("", 'Ә')));
957 }
958
959 #[test]
960 fn character() {
961 let a: &[u8] = b"abcd";
962 let b: &[u8] = b"1234";
963 let c: &[u8] = b"a123";
964 let d: &[u8] = "azé12".as_bytes();
965 let e: &[u8] = b" ";
966 let f: &[u8] = b" ;";
967 assert_parse!(alpha1(a), Err(Err::Incomplete(Needed::new(1))));
969 assert_eq!(alpha1(b), Err(Err::Error((b, ErrorKind::Alpha))));
970 assert_eq!(alpha1::<_, (_, ErrorKind)>(c), Ok((&c[1..], &b"a"[..])));
971 assert_eq!(
972 alpha1::<_, (_, ErrorKind)>(d),
973 Ok(("é12".as_bytes(), &b"az"[..]))
974 );
975 assert_eq!(digit1(a), Err(Err::Error((a, ErrorKind::Digit))));
976 assert_eq!(
977 digit1::<_, (_, ErrorKind)>(b),
978 Err(Err::Incomplete(Needed::new(1)))
979 );
980 assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit))));
981 assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit))));
982 assert_eq!(
983 hex_digit1::<_, (_, ErrorKind)>(a),
984 Err(Err::Incomplete(Needed::new(1)))
985 );
986 assert_eq!(
987 hex_digit1::<_, (_, ErrorKind)>(b),
988 Err(Err::Incomplete(Needed::new(1)))
989 );
990 assert_eq!(
991 hex_digit1::<_, (_, ErrorKind)>(c),
992 Err(Err::Incomplete(Needed::new(1)))
993 );
994 assert_eq!(
995 hex_digit1::<_, (_, ErrorKind)>(d),
996 Ok(("zé12".as_bytes(), &b"a"[..]))
997 );
998 assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit))));
999 assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit))));
1000 assert_eq!(
1001 oct_digit1::<_, (_, ErrorKind)>(b),
1002 Err(Err::Incomplete(Needed::new(1)))
1003 );
1004 assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit))));
1005 assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit))));
1006 assert_eq!(
1007 alphanumeric1::<_, (_, ErrorKind)>(a),
1008 Err(Err::Incomplete(Needed::new(1)))
1009 );
1010 assert_eq!(
1012 alphanumeric1::<_, (_, ErrorKind)>(c),
1013 Err(Err::Incomplete(Needed::new(1)))
1014 );
1015 assert_eq!(
1016 alphanumeric1::<_, (_, ErrorKind)>(d),
1017 Ok(("é12".as_bytes(), &b"az"[..]))
1018 );
1019 assert_eq!(
1020 space1::<_, (_, ErrorKind)>(e),
1021 Err(Err::Incomplete(Needed::new(1)))
1022 );
1023 assert_eq!(space1::<_, (_, ErrorKind)>(f), Ok((&b";"[..], &b" "[..])));
1024 }
1025
1026 #[cfg(feature = "alloc")]
1027 #[test]
1028 fn character_s() {
1029 let a = "abcd";
1030 let b = "1234";
1031 let c = "a123";
1032 let d = "azé12";
1033 let e = " ";
1034 assert_eq!(
1035 alpha1::<_, (_, ErrorKind)>(a),
1036 Err(Err::Incomplete(Needed::new(1)))
1037 );
1038 assert_eq!(alpha1(b), Err(Err::Error((b, ErrorKind::Alpha))));
1039 assert_eq!(alpha1::<_, (_, ErrorKind)>(c), Ok((&c[1..], &"a"[..])));
1040 assert_eq!(alpha1::<_, (_, ErrorKind)>(d), Ok(("é12", &"az"[..])));
1041 assert_eq!(digit1(a), Err(Err::Error((a, ErrorKind::Digit))));
1042 assert_eq!(
1043 digit1::<_, (_, ErrorKind)>(b),
1044 Err(Err::Incomplete(Needed::new(1)))
1045 );
1046 assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit))));
1047 assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit))));
1048 assert_eq!(
1049 hex_digit1::<_, (_, ErrorKind)>(a),
1050 Err(Err::Incomplete(Needed::new(1)))
1051 );
1052 assert_eq!(
1053 hex_digit1::<_, (_, ErrorKind)>(b),
1054 Err(Err::Incomplete(Needed::new(1)))
1055 );
1056 assert_eq!(
1057 hex_digit1::<_, (_, ErrorKind)>(c),
1058 Err(Err::Incomplete(Needed::new(1)))
1059 );
1060 assert_eq!(hex_digit1::<_, (_, ErrorKind)>(d), Ok(("zé12", &"a"[..])));
1061 assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit))));
1062 assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit))));
1063 assert_eq!(
1064 oct_digit1::<_, (_, ErrorKind)>(b),
1065 Err(Err::Incomplete(Needed::new(1)))
1066 );
1067 assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit))));
1068 assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit))));
1069 assert_eq!(
1070 alphanumeric1::<_, (_, ErrorKind)>(a),
1071 Err(Err::Incomplete(Needed::new(1)))
1072 );
1073 assert_eq!(
1075 alphanumeric1::<_, (_, ErrorKind)>(c),
1076 Err(Err::Incomplete(Needed::new(1)))
1077 );
1078 assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(d), Ok(("é12", "az")));
1079 assert_eq!(
1080 space1::<_, (_, ErrorKind)>(e),
1081 Err(Err::Incomplete(Needed::new(1)))
1082 );
1083 }
1084
1085 use crate::input::Offset;
1086 #[test]
1087 fn offset() {
1088 let a = &b"abcd;"[..];
1089 let b = &b"1234;"[..];
1090 let c = &b"a123;"[..];
1091 let d = &b" \t;"[..];
1092 let e = &b" \t\r\n;"[..];
1093 let f = &b"123abcDEF;"[..];
1094
1095 match alpha1::<_, (_, ErrorKind)>(a) {
1096 Ok((i, _)) => {
1097 assert_eq!(a.offset(i) + i.len(), a.len());
1098 }
1099 _ => panic!("wrong return type in offset test for alpha"),
1100 }
1101 match digit1::<_, (_, ErrorKind)>(b) {
1102 Ok((i, _)) => {
1103 assert_eq!(b.offset(i) + i.len(), b.len());
1104 }
1105 _ => panic!("wrong return type in offset test for digit"),
1106 }
1107 match alphanumeric1::<_, (_, ErrorKind)>(c) {
1108 Ok((i, _)) => {
1109 assert_eq!(c.offset(i) + i.len(), c.len());
1110 }
1111 _ => panic!("wrong return type in offset test for alphanumeric"),
1112 }
1113 match space1::<_, (_, ErrorKind)>(d) {
1114 Ok((i, _)) => {
1115 assert_eq!(d.offset(i) + i.len(), d.len());
1116 }
1117 _ => panic!("wrong return type in offset test for space"),
1118 }
1119 match multispace1::<_, (_, ErrorKind)>(e) {
1120 Ok((i, _)) => {
1121 assert_eq!(e.offset(i) + i.len(), e.len());
1122 }
1123 _ => panic!("wrong return type in offset test for multispace"),
1124 }
1125 match hex_digit1::<_, (_, ErrorKind)>(f) {
1126 Ok((i, _)) => {
1127 assert_eq!(f.offset(i) + i.len(), f.len());
1128 }
1129 _ => panic!("wrong return type in offset test for hex_digit"),
1130 }
1131 match oct_digit1::<_, (_, ErrorKind)>(f) {
1132 Ok((i, _)) => {
1133 assert_eq!(f.offset(i) + i.len(), f.len());
1134 }
1135 _ => panic!("wrong return type in offset test for oct_digit"),
1136 }
1137 }
1138
1139 #[test]
1140 fn is_not_line_ending_bytes() {
1141 let a: &[u8] = b"ab12cd\nefgh";
1142 assert_eq!(
1143 not_line_ending::<_, (_, ErrorKind)>(a),
1144 Ok((&b"\nefgh"[..], &b"ab12cd"[..]))
1145 );
1146
1147 let b: &[u8] = b"ab12cd\nefgh\nijkl";
1148 assert_eq!(
1149 not_line_ending::<_, (_, ErrorKind)>(b),
1150 Ok((&b"\nefgh\nijkl"[..], &b"ab12cd"[..]))
1151 );
1152
1153 let c: &[u8] = b"ab12cd\r\nefgh\nijkl";
1154 assert_eq!(
1155 not_line_ending::<_, (_, ErrorKind)>(c),
1156 Ok((&b"\r\nefgh\nijkl"[..], &b"ab12cd"[..]))
1157 );
1158
1159 let d: &[u8] = b"ab12cd";
1160 assert_eq!(
1161 not_line_ending::<_, (_, ErrorKind)>(d),
1162 Err(Err::Incomplete(Needed::Unknown))
1163 );
1164 }
1165
1166 #[test]
1167 fn is_not_line_ending_str() {
1168 let f = "βèƒôřè\rÂßÇáƒƭèř";
1186 assert_eq!(not_line_ending(f), Err(Err::Error((f, ErrorKind::Tag))));
1187
1188 let g2: &str = "ab12cd";
1189 assert_eq!(
1190 not_line_ending::<_, (_, ErrorKind)>(g2),
1191 Err(Err::Incomplete(Needed::Unknown))
1192 );
1193 }
1194
1195 #[test]
1196 fn hex_digit_test() {
1197 let i = &b"0123456789abcdefABCDEF;"[..];
1198 assert_parse!(hex_digit1(i), Ok((&b";"[..], &i[..i.len() - 1])));
1199
1200 let i = &b"g"[..];
1201 assert_parse!(
1202 hex_digit1(i),
1203 Err(Err::Error(error_position!(i, ErrorKind::HexDigit)))
1204 );
1205
1206 let i = &b"G"[..];
1207 assert_parse!(
1208 hex_digit1(i),
1209 Err(Err::Error(error_position!(i, ErrorKind::HexDigit)))
1210 );
1211
1212 assert!(AsChar::is_hex_digit(b'0'));
1213 assert!(AsChar::is_hex_digit(b'9'));
1214 assert!(AsChar::is_hex_digit(b'a'));
1215 assert!(AsChar::is_hex_digit(b'f'));
1216 assert!(AsChar::is_hex_digit(b'A'));
1217 assert!(AsChar::is_hex_digit(b'F'));
1218 assert!(!AsChar::is_hex_digit(b'g'));
1219 assert!(!AsChar::is_hex_digit(b'G'));
1220 assert!(!AsChar::is_hex_digit(b'/'));
1221 assert!(!AsChar::is_hex_digit(b':'));
1222 assert!(!AsChar::is_hex_digit(b'@'));
1223 assert!(!AsChar::is_hex_digit(b'\x60'));
1224 }
1225
1226 #[test]
1227 fn oct_digit_test() {
1228 let i = &b"01234567;"[..];
1229 assert_parse!(oct_digit1(i), Ok((&b";"[..], &i[..i.len() - 1])));
1230
1231 let i = &b"8"[..];
1232 assert_parse!(
1233 oct_digit1(i),
1234 Err(Err::Error(error_position!(i, ErrorKind::OctDigit)))
1235 );
1236
1237 assert!(AsChar::is_oct_digit(b'0'));
1238 assert!(AsChar::is_oct_digit(b'7'));
1239 assert!(!AsChar::is_oct_digit(b'8'));
1240 assert!(!AsChar::is_oct_digit(b'9'));
1241 assert!(!AsChar::is_oct_digit(b'a'));
1242 assert!(!AsChar::is_oct_digit(b'A'));
1243 assert!(!AsChar::is_oct_digit(b'/'));
1244 assert!(!AsChar::is_oct_digit(b':'));
1245 assert!(!AsChar::is_oct_digit(b'@'));
1246 assert!(!AsChar::is_oct_digit(b'\x60'));
1247 }
1248
1249 #[test]
1250 fn full_line_windows() {
1251 fn take_full_line(i: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
1252 pair(not_line_ending, line_ending)(i)
1253 }
1254 let input = b"abc\r\n";
1255 let output = take_full_line(input);
1256 assert_eq!(output, Ok((&b""[..], (&b"abc"[..], &b"\r\n"[..]))));
1257 }
1258
1259 #[test]
1260 fn full_line_unix() {
1261 fn take_full_line(i: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
1262 pair(not_line_ending, line_ending)(i)
1263 }
1264 let input = b"abc\n";
1265 let output = take_full_line(input);
1266 assert_eq!(output, Ok((&b""[..], (&b"abc"[..], &b"\n"[..]))));
1267 }
1268
1269 #[test]
1270 fn check_windows_lineending() {
1271 let input = b"\r\n";
1272 let output = line_ending(&input[..]);
1273 assert_parse!(output, Ok((&b""[..], &b"\r\n"[..])));
1274 }
1275
1276 #[test]
1277 fn check_unix_lineending() {
1278 let input = b"\n";
1279 let output = line_ending(&input[..]);
1280 assert_parse!(output, Ok((&b""[..], &b"\n"[..])));
1281 }
1282
1283 #[test]
1284 fn cr_lf() {
1285 assert_parse!(crlf(&b"\r\na"[..]), Ok((&b"a"[..], &b"\r\n"[..])));
1286 assert_parse!(crlf(&b"\r"[..]), Err(Err::Incomplete(Needed::new(2))));
1287 assert_parse!(
1288 crlf(&b"\ra"[..]),
1289 Err(Err::Error(error_position!(&b"\ra"[..], ErrorKind::CrLf)))
1290 );
1291
1292 assert_parse!(crlf("\r\na"), Ok(("a", "\r\n")));
1293 assert_parse!(crlf("\r"), Err(Err::Incomplete(Needed::new(2))));
1294 assert_parse!(
1295 crlf("\ra"),
1296 Err(Err::Error(error_position!("\ra", ErrorKind::CrLf)))
1297 );
1298 }
1299
1300 #[test]
1301 fn end_of_line() {
1302 assert_parse!(line_ending(&b"\na"[..]), Ok((&b"a"[..], &b"\n"[..])));
1303 assert_parse!(line_ending(&b"\r\na"[..]), Ok((&b"a"[..], &b"\r\n"[..])));
1304 assert_parse!(
1305 line_ending(&b"\r"[..]),
1306 Err(Err::Incomplete(Needed::new(2)))
1307 );
1308 assert_parse!(
1309 line_ending(&b"\ra"[..]),
1310 Err(Err::Error(error_position!(&b"\ra"[..], ErrorKind::CrLf)))
1311 );
1312
1313 assert_parse!(line_ending("\na"), Ok(("a", "\n")));
1314 assert_parse!(line_ending("\r\na"), Ok(("a", "\r\n")));
1315 assert_parse!(line_ending("\r"), Err(Err::Incomplete(Needed::new(2))));
1316 assert_parse!(
1317 line_ending("\ra"),
1318 Err(Err::Error(error_position!("\ra", ErrorKind::CrLf)))
1319 );
1320 }
1321
1322 fn digit_to_i16(input: &str) -> IResult<&str, i16> {
1323 let i = input;
1324 let (i, opt_sign) = opt(alt((char('+'), char('-'))))(i)?;
1325 let sign = match opt_sign {
1326 Some('+') => true,
1327 Some('-') => false,
1328 _ => true,
1329 };
1330
1331 let (i, s) = match digit1::<_, crate::error::Error<_>>(i) {
1332 Ok((i, s)) => (i, s),
1333 Err(Err::Incomplete(i)) => return Err(Err::Incomplete(i)),
1334 Err(_) => {
1335 return Err(Err::Error(crate::error::Error::from_error_kind(
1336 input,
1337 ErrorKind::Digit,
1338 )))
1339 }
1340 };
1341 match s.parse_to() {
1342 Some(n) => {
1343 if sign {
1344 Ok((i, n))
1345 } else {
1346 Ok((i, -n))
1347 }
1348 }
1349 None => Err(Err::Error(crate::error::Error::from_error_kind(
1350 i,
1351 ErrorKind::Digit,
1352 ))),
1353 }
1354 }
1355
1356 fn digit_to_u32(i: &str) -> IResult<&str, u32> {
1357 let (i, s) = digit1(i)?;
1358 match s.parse_to() {
1359 Some(n) => Ok((i, n)),
1360 None => Err(Err::Error(crate::error::Error::from_error_kind(
1361 i,
1362 ErrorKind::Digit,
1363 ))),
1364 }
1365 }
1366
1367 #[test]
1368 fn one_of_test() {
1369 fn f(i: &[u8]) -> IResult<&[u8], char> {
1370 one_of("ab")(i)
1371 }
1372
1373 let a = &b"abcd"[..];
1374 assert_eq!(f(a), Ok((&b"bcd"[..], 'a')));
1375
1376 let b = &b"cde"[..];
1377 assert_eq!(f(b), Err(Err::Error(error_position!(b, ErrorKind::OneOf))));
1378
1379 fn utf8(i: &str) -> IResult<&str, char> {
1380 one_of("+\u{FF0B}")(i)
1381 }
1382
1383 assert!(utf8("+").is_ok());
1384 assert!(utf8("\u{FF0B}").is_ok());
1385 }
1386
1387 #[test]
1388 fn none_of_test() {
1389 fn f(i: &[u8]) -> IResult<&[u8], char> {
1390 none_of("ab")(i)
1391 }
1392
1393 let a = &b"abcd"[..];
1394 assert_eq!(f(a), Err(Err::Error(error_position!(a, ErrorKind::NoneOf))));
1395
1396 let b = &b"cde"[..];
1397 assert_eq!(f(b), Ok((&b"de"[..], 'c')));
1398 }
1399
1400 #[test]
1401 fn char_byteslice() {
1402 fn f(i: &[u8]) -> IResult<&[u8], char> {
1403 char('c')(i)
1404 }
1405
1406 let a = &b"abcd"[..];
1407 assert_eq!(f(a), Err(Err::Error(error_position!(a, ErrorKind::Char))));
1408
1409 let b = &b"cde"[..];
1410 assert_eq!(f(b), Ok((&b"de"[..], 'c')));
1411 }
1412
1413 #[test]
1414 fn char_str() {
1415 fn f(i: &str) -> IResult<&str, char> {
1416 char('c')(i)
1417 }
1418
1419 let a = &"abcd"[..];
1420 assert_eq!(f(a), Err(Err::Error(error_position!(a, ErrorKind::Char))));
1421
1422 let b = &"cde"[..];
1423 assert_eq!(f(b), Ok((&"de"[..], 'c')));
1424 }
1425
1426 proptest! {
1427 #[test]
1428 fn ints(s in "\\PC*") {
1429 let res1 = digit_to_i16(&s);
1430 let res2 = i16(s.as_str());
1431 assert_eq!(res1, res2);
1432 }
1433
1434 #[test]
1435 fn uints(s in "\\PC*") {
1436 let res1 = digit_to_u32(&s);
1437 let res2 = u32(s.as_str());
1438 assert_eq!(res1, res2);
1439 }
1440 }
1441}