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};
18
19#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::one_of`")]
38pub fn char<I, Error: ParseError<I>>(c: char) -> impl Fn(I) -> IResult<I, char, Error>
39where
40 I: Slice<RangeFrom<usize>> + InputIter,
41 <I as InputIter>::Item: AsChar,
42{
43 move |i: I| char_internal(i, c)
44}
45
46pub(crate) fn char_internal<I, Error: ParseError<I>>(i: I, c: char) -> IResult<I, char, Error>
47where
48 I: Slice<RangeFrom<usize>> + InputIter,
49 <I as InputIter>::Item: AsChar,
50{
51 match (i).iter_elements().next().map(|t| {
52 let b = t.as_char() == c;
53 (&c, b)
54 }) {
55 Some((c, true)) => Ok((i.slice(c.len()..), c.as_char())),
56 _ => Err(Err::Error(Error::from_char(i, c))),
57 }
58}
59
60#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::one_of`")]
78pub fn satisfy<F, I, Error: ParseError<I>>(cond: F) -> impl Fn(I) -> IResult<I, char, Error>
79where
80 I: Slice<RangeFrom<usize>> + InputIter,
81 <I as InputIter>::Item: AsChar,
82 F: Fn(char) -> bool,
83{
84 move |i: I| satisfy_internal(i, &cond)
85}
86
87pub(crate) fn satisfy_internal<F, I, Error: ParseError<I>>(
88 i: I,
89 cond: &F,
90) -> IResult<I, char, Error>
91where
92 I: Slice<RangeFrom<usize>> + InputIter,
93 <I as InputIter>::Item: AsChar,
94 F: Fn(char) -> bool,
95{
96 match (i).iter_elements().next().map(|t| {
97 let c = t.as_char();
98 let b = cond(c);
99 (c, b)
100 }) {
101 Some((c, true)) => Ok((i.slice(c.len()..), c)),
102 _ => Err(Err::Error(Error::from_error_kind(i, ErrorKind::Satisfy))),
103 }
104}
105
106#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::one_of`")]
121pub fn one_of<I, T, Error: ParseError<I>>(list: T) -> impl Fn(I) -> IResult<I, char, Error>
122where
123 I: Slice<RangeFrom<usize>> + InputIter + InputLength,
124 <I as InputIter>::Item: AsChar + Copy,
125 T: FindToken<<I as InputIter>::Item>,
126{
127 move |i: I| crate::bytes::complete::one_of_internal(i, &list).map(|(i, c)| (i, c.as_char()))
128}
129
130#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::none_of`")]
145pub fn none_of<I, T, Error: ParseError<I>>(list: T) -> impl Fn(I) -> IResult<I, char, Error>
146where
147 I: Slice<RangeFrom<usize>> + InputLength + InputIter,
148 <I as InputIter>::Item: AsChar + Copy,
149 T: FindToken<<I as InputIter>::Item>,
150{
151 move |i: I| crate::bytes::complete::none_of_internal(i, &list).map(|(i, c)| (i, c.as_char()))
152}
153
154#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::crlf`")]
173pub fn crlf<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
174where
175 T: Slice<Range<usize>> + Slice<RangeFrom<usize>>,
176 T: InputIter,
177 T: IntoOutput,
178 T: Compare<&'static str>,
179{
180 match input.compare("\r\n") {
181 CompareResult::Ok => Ok((input.slice(2..), input.slice(0..2))).into_output(),
183 _ => {
184 let e: ErrorKind = ErrorKind::CrLf;
185 Err(Err::Error(E::from_error_kind(input, e)))
186 }
187 }
188}
189
190#[deprecated(
213 since = "8.0.0",
214 note = "Replaced with `nom8::character::not_line_ending`"
215)]
216pub fn not_line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
217where
218 T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
219 T: InputIter + InputLength,
220 T: IntoOutput,
221 T: Compare<&'static str>,
222 <T as InputIter>::Item: AsChar,
223 <T as InputIter>::Item: AsChar,
224{
225 match input.position(|item| {
226 let c = item.as_char();
227 c == '\r' || c == '\n'
228 }) {
229 None => Ok((input.slice(input.input_len()..), input)).into_output(),
230 Some(index) => {
231 let mut it = input.slice(index..).iter_elements();
232 let nth = it.next().unwrap().as_char();
233 if nth == '\r' {
234 let sliced = input.slice(index..);
235 let comp = sliced.compare("\r\n");
236 match comp {
237 CompareResult::Ok => Ok((input.slice(index..), input.slice(..index))).into_output(),
239 _ => {
240 let e: ErrorKind = ErrorKind::Tag;
241 Err(Err::Error(E::from_error_kind(input, e)))
242 }
243 }
244 } else {
245 Ok((input.slice(index..), input.slice(..index))).into_output()
246 }
247 }
248 }
249}
250
251#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::line_ending`")]
270pub fn line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
271where
272 T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
273 T: InputIter + InputLength,
274 T: IntoOutput,
275 T: Compare<&'static str>,
276{
277 match input.compare("\n") {
278 CompareResult::Ok => Ok((input.slice(1..), input.slice(0..1))).into_output(),
279 CompareResult::Incomplete => Err(Err::Error(E::from_error_kind(input, ErrorKind::CrLf))),
280 CompareResult::Error => {
281 match input.compare("\r\n") {
282 CompareResult::Ok => Ok((input.slice(2..), input.slice(0..2))).into_output(),
284 _ => Err(Err::Error(E::from_error_kind(input, ErrorKind::CrLf))),
285 }
286 }
287 }
288}
289
290#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::newline`")]
309pub fn newline<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error>
310where
311 I: Slice<RangeFrom<usize>> + InputIter,
312 <I as InputIter>::Item: AsChar,
313{
314 char('\n')(input)
315}
316
317#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::tab`")]
336pub fn tab<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error>
337where
338 I: Slice<RangeFrom<usize>> + InputIter,
339 <I as InputIter>::Item: AsChar,
340{
341 char('\t')(input)
342}
343
344#[deprecated(since = "8.0.0", note = "Replaced with `nom8::bytes::any`")]
362pub fn anychar<T, E: ParseError<T>>(input: T) -> IResult<T, char, E>
363where
364 T: InputIter + InputLength + Slice<RangeFrom<usize>>,
365 <T as InputIter>::Item: AsChar,
366{
367 crate::bytes::complete::any(input).map(|(i, c)| (i, c.as_char()))
368}
369
370#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::alpha0`")]
390pub fn alpha0<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
391where
392 T: InputTakeAtPosition,
393 T: IntoOutput,
394 <T as InputTakeAtPosition>::Item: AsChar,
395{
396 input
397 .split_at_position_complete(|item| !item.is_alpha())
398 .into_output()
399}
400
401#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::alpha1`")]
421pub fn alpha1<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
422where
423 T: InputTakeAtPosition,
424 T: IntoOutput,
425 <T as InputTakeAtPosition>::Item: AsChar,
426{
427 input
428 .split_at_position1_complete(|item| !item.is_alpha(), ErrorKind::Alpha)
429 .into_output()
430}
431
432#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::digit0`")]
453pub fn digit0<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
454where
455 T: InputTakeAtPosition,
456 T: IntoOutput,
457 <T as InputTakeAtPosition>::Item: AsChar,
458{
459 input
460 .split_at_position_complete(|item| !item.is_dec_digit())
461 .into_output()
462}
463
464#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::digit1`")]
502pub fn digit1<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
503where
504 T: InputTakeAtPosition,
505 T: IntoOutput,
506 <T as InputTakeAtPosition>::Item: AsChar,
507{
508 input
509 .split_at_position1_complete(|item| !item.is_dec_digit(), ErrorKind::Digit)
510 .into_output()
511}
512
513#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::hex_digit0`")]
532pub fn hex_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
533where
534 T: InputTakeAtPosition,
535 T: IntoOutput,
536 <T as InputTakeAtPosition>::Item: AsChar,
537{
538 input
539 .split_at_position_complete(|item| !item.is_hex_digit())
540 .into_output()
541}
542#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::hex_digit1`")]
562pub fn hex_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
563where
564 T: InputTakeAtPosition,
565 T: IntoOutput,
566 <T as InputTakeAtPosition>::Item: AsChar,
567{
568 input
569 .split_at_position1_complete(|item| !item.is_hex_digit(), ErrorKind::HexDigit)
570 .into_output()
571}
572
573#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::oct_digit0`")]
593pub fn oct_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
594where
595 T: InputTakeAtPosition,
596 T: IntoOutput,
597 <T as InputTakeAtPosition>::Item: AsChar,
598{
599 input
600 .split_at_position_complete(|item| !item.is_oct_digit())
601 .into_output()
602}
603
604#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::oct_digit1`")]
624pub fn oct_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
625where
626 T: InputTakeAtPosition,
627 T: IntoOutput,
628 <T as InputTakeAtPosition>::Item: AsChar,
629{
630 input
631 .split_at_position1_complete(|item| !item.is_oct_digit(), ErrorKind::OctDigit)
632 .into_output()
633}
634
635#[deprecated(
655 since = "8.0.0",
656 note = "Replaced with `nom8::character::alphanumeric0`"
657)]
658pub fn alphanumeric0<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
659where
660 T: InputTakeAtPosition,
661 T: IntoOutput,
662 <T as InputTakeAtPosition>::Item: AsChar,
663{
664 input
665 .split_at_position_complete(|item| !item.is_alphanum())
666 .into_output()
667}
668
669#[deprecated(
689 since = "8.0.0",
690 note = "Replaced with `nom8::character::alphanumeric1`"
691)]
692pub fn alphanumeric1<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
693where
694 T: InputTakeAtPosition,
695 T: IntoOutput,
696 <T as InputTakeAtPosition>::Item: AsChar,
697{
698 input
699 .split_at_position1_complete(|item| !item.is_alphanum(), ErrorKind::AlphaNumeric)
700 .into_output()
701}
702
703#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::space0`")]
723pub fn space0<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
724where
725 T: InputTakeAtPosition,
726 T: IntoOutput,
727 <T as InputTakeAtPosition>::Item: AsChar + Clone,
728{
729 input
730 .split_at_position_complete(|item| {
731 let c = item.as_char();
732 !(c == ' ' || c == '\t')
733 })
734 .into_output()
735}
736
737#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::space1`")]
757pub fn space1<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
758where
759 T: InputTakeAtPosition,
760 T: IntoOutput,
761 <T as InputTakeAtPosition>::Item: AsChar + Clone,
762{
763 input
764 .split_at_position1_complete(
765 |item| {
766 let c = item.as_char();
767 !(c == ' ' || c == '\t')
768 },
769 ErrorKind::Space,
770 )
771 .into_output()
772}
773
774#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::multispace0`")]
794pub fn multispace0<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
795where
796 T: InputTakeAtPosition,
797 T: IntoOutput,
798 <T as InputTakeAtPosition>::Item: AsChar + Clone,
799{
800 input
801 .split_at_position_complete(|item| {
802 let c = item.as_char();
803 !(c == ' ' || c == '\t' || c == '\r' || c == '\n')
804 })
805 .into_output()
806}
807
808#[deprecated(since = "8.0.0", note = "Replaced with `nom8::character::multispace1`")]
828pub fn multispace1<T, E: ParseError<T>>(input: T) -> IResult<T, <T as IntoOutput>::Output, E>
829where
830 T: InputTakeAtPosition,
831 T: IntoOutput,
832 <T as InputTakeAtPosition>::Item: AsChar + Clone,
833{
834 input
835 .split_at_position1_complete(
836 |item| {
837 let c = item.as_char();
838 !(c == ' ' || c == '\t' || c == '\r' || c == '\n')
839 },
840 ErrorKind::MultiSpace,
841 )
842 .into_output()
843}
844
845pub(crate) fn sign<T, E: ParseError<T>>(input: T) -> IResult<T, bool, E>
846where
847 T: Clone + InputTake,
848 T: IntoOutput,
849 T: for<'a> Compare<&'a [u8]>,
850{
851 use crate::bytes::complete::tag;
852 use crate::combinator::value;
853
854 let (i, opt_sign) = opt(alt((
855 value(false, tag(&b"-"[..])),
856 value(true, tag(&b"+"[..])),
857 )))(input)?;
858 let sign = opt_sign.unwrap_or(true);
859
860 Ok((i, sign))
861}
862
863#[doc(hidden)]
864macro_rules! ints {
865 ($($t:tt)+) => {
866 $(
867 pub fn $t<T, E: ParseError<T>>(input: T) -> IResult<T, $t, E>
871 where
872 T: InputIter + Slice<RangeFrom<usize>> + InputLength + InputTake + Clone,
873 T: IntoOutput,
874 <T as InputIter>::Item: AsChar,
875 T: for <'a> Compare<&'a[u8]>,
876 {
877 let (i, sign) = sign(input.clone())?;
878
879 if i.input_len() == 0 {
880 return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit)));
881 }
882
883 let mut value: $t = 0;
884 if sign {
885 for (pos, c) in i.iter_indices() {
886 match c.as_char().to_digit(10) {
887 None => {
888 if pos == 0 {
889 return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit)));
890 } else {
891 return Ok((i.slice(pos..), value));
892 }
893 },
894 Some(d) => match value.checked_mul(10).and_then(|v| v.checked_add(d as $t)) {
895 None => return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit))),
896 Some(v) => value = v,
897 }
898 }
899 }
900 } else {
901 for (pos, c) in i.iter_indices() {
902 match c.as_char().to_digit(10) {
903 None => {
904 if pos == 0 {
905 return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit)));
906 } else {
907 return Ok((i.slice(pos..), value));
908 }
909 },
910 Some(d) => match value.checked_mul(10).and_then(|v| v.checked_sub(d as $t)) {
911 None => return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit))),
912 Some(v) => value = v,
913 }
914 }
915 }
916 }
917
918 Ok((i.slice(i.input_len()..), value))
919 }
920 )+
921 }
922}
923
924ints! { i8 i16 i32 i64 i128 }
925
926#[doc(hidden)]
927macro_rules! uints {
928 ($($t:tt)+) => {
929 $(
930 pub fn $t<T, E: ParseError<T>>(input: T) -> IResult<T, $t, E>
934 where
935 T: InputIter + Slice<RangeFrom<usize>> + InputLength,
936 T: IntoOutput,
937 <T as InputIter>::Item: AsChar,
938 {
939 let i = input;
940
941 if i.input_len() == 0 {
942 return Err(Err::Error(E::from_error_kind(i, ErrorKind::Digit)));
943 }
944
945 let mut value: $t = 0;
946 for (pos, c) in i.iter_indices() {
947 match c.as_char().to_digit(10) {
948 None => {
949 if pos == 0 {
950 return Err(Err::Error(E::from_error_kind(i, ErrorKind::Digit)));
951 } else {
952 return Ok((i.slice(pos..), value));
953 }
954 },
955 Some(d) => match value.checked_mul(10).and_then(|v| v.checked_add(d as $t)) {
956 None => return Err(Err::Error(E::from_error_kind(i, ErrorKind::Digit))),
957 Some(v) => value = v,
958 }
959 }
960 }
961
962 Ok((i.slice(i.input_len()..), value))
963 }
964 )+
965 }
966}
967
968uints! { u8 u16 u32 u64 u128 }
969
970#[cfg(test)]
971mod tests {
972 use super::*;
973 use crate::input::ParseTo;
974 use crate::Err;
975 use proptest::prelude::*;
976
977 macro_rules! assert_parse(
978 ($left: expr, $right: expr) => {
979 let res: $crate::IResult<_, _, (_, ErrorKind)> = $left;
980 assert_eq!(res, $right);
981 };
982 );
983
984 #[test]
985 fn character() {
986 let empty: &[u8] = b"";
987 let a: &[u8] = b"abcd";
988 let b: &[u8] = b"1234";
989 let c: &[u8] = b"a123";
990 let d: &[u8] = "azé12".as_bytes();
991 let e: &[u8] = b" ";
992 let f: &[u8] = b" ;";
993 assert_parse!(alpha1(a), Ok((empty, a)));
995 assert_eq!(alpha1(b), Err(Err::Error((b, ErrorKind::Alpha))));
996 assert_eq!(alpha1::<_, (_, ErrorKind)>(c), Ok((&c[1..], &b"a"[..])));
997 assert_eq!(
998 alpha1::<_, (_, ErrorKind)>(d),
999 Ok(("é12".as_bytes(), &b"az"[..]))
1000 );
1001 assert_eq!(digit1(a), Err(Err::Error((a, ErrorKind::Digit))));
1002 assert_eq!(digit1::<_, (_, ErrorKind)>(b), Ok((empty, b)));
1003 assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit))));
1004 assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit))));
1005 assert_eq!(hex_digit1::<_, (_, ErrorKind)>(a), Ok((empty, a)));
1006 assert_eq!(hex_digit1::<_, (_, ErrorKind)>(b), Ok((empty, b)));
1007 assert_eq!(hex_digit1::<_, (_, ErrorKind)>(c), Ok((empty, c)));
1008 assert_eq!(
1009 hex_digit1::<_, (_, ErrorKind)>(d),
1010 Ok(("zé12".as_bytes(), &b"a"[..]))
1011 );
1012 assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit))));
1013 assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit))));
1014 assert_eq!(oct_digit1::<_, (_, ErrorKind)>(b), Ok((empty, b)));
1015 assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit))));
1016 assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit))));
1017 assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(a), Ok((empty, a)));
1018 assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(c), Ok((empty, c)));
1020 assert_eq!(
1021 alphanumeric1::<_, (_, ErrorKind)>(d),
1022 Ok(("é12".as_bytes(), &b"az"[..]))
1023 );
1024 assert_eq!(space1::<_, (_, ErrorKind)>(e), Ok((empty, e)));
1025 assert_eq!(space1::<_, (_, ErrorKind)>(f), Ok((&b";"[..], &b" "[..])));
1026 }
1027
1028 #[cfg(feature = "alloc")]
1029 #[test]
1030 fn character_s() {
1031 let empty = "";
1032 let a = "abcd";
1033 let b = "1234";
1034 let c = "a123";
1035 let d = "azé12";
1036 let e = " ";
1037 assert_eq!(alpha1::<_, (_, ErrorKind)>(a), Ok((empty, a)));
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!(digit1::<_, (_, ErrorKind)>(b), Ok((empty, b)));
1043 assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit))));
1044 assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit))));
1045 assert_eq!(hex_digit1::<_, (_, ErrorKind)>(a), Ok((empty, a)));
1046 assert_eq!(hex_digit1::<_, (_, ErrorKind)>(b), Ok((empty, b)));
1047 assert_eq!(hex_digit1::<_, (_, ErrorKind)>(c), Ok((empty, c)));
1048 assert_eq!(hex_digit1::<_, (_, ErrorKind)>(d), Ok(("zé12", &"a"[..])));
1049 assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit))));
1050 assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit))));
1051 assert_eq!(oct_digit1::<_, (_, ErrorKind)>(b), Ok((empty, b)));
1052 assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit))));
1053 assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit))));
1054 assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(a), Ok((empty, a)));
1055 assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(c), Ok((empty, c)));
1057 assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(d), Ok(("é12", "az")));
1058 assert_eq!(space1::<_, (_, ErrorKind)>(e), Ok((empty, e)));
1059 }
1060
1061 use crate::input::Offset;
1062 #[test]
1063 fn offset() {
1064 let a = &b"abcd;"[..];
1065 let b = &b"1234;"[..];
1066 let c = &b"a123;"[..];
1067 let d = &b" \t;"[..];
1068 let e = &b" \t\r\n;"[..];
1069 let f = &b"123abcDEF;"[..];
1070
1071 match alpha1::<_, (_, ErrorKind)>(a) {
1072 Ok((i, _)) => {
1073 assert_eq!(a.offset(i) + i.len(), a.len());
1074 }
1075 _ => panic!("wrong return type in offset test for alpha"),
1076 }
1077 match digit1::<_, (_, ErrorKind)>(b) {
1078 Ok((i, _)) => {
1079 assert_eq!(b.offset(i) + i.len(), b.len());
1080 }
1081 _ => panic!("wrong return type in offset test for digit"),
1082 }
1083 match alphanumeric1::<_, (_, ErrorKind)>(c) {
1084 Ok((i, _)) => {
1085 assert_eq!(c.offset(i) + i.len(), c.len());
1086 }
1087 _ => panic!("wrong return type in offset test for alphanumeric"),
1088 }
1089 match space1::<_, (_, ErrorKind)>(d) {
1090 Ok((i, _)) => {
1091 assert_eq!(d.offset(i) + i.len(), d.len());
1092 }
1093 _ => panic!("wrong return type in offset test for space"),
1094 }
1095 match multispace1::<_, (_, ErrorKind)>(e) {
1096 Ok((i, _)) => {
1097 assert_eq!(e.offset(i) + i.len(), e.len());
1098 }
1099 _ => panic!("wrong return type in offset test for multispace"),
1100 }
1101 match hex_digit1::<_, (_, ErrorKind)>(f) {
1102 Ok((i, _)) => {
1103 assert_eq!(f.offset(i) + i.len(), f.len());
1104 }
1105 _ => panic!("wrong return type in offset test for hex_digit"),
1106 }
1107 match oct_digit1::<_, (_, ErrorKind)>(f) {
1108 Ok((i, _)) => {
1109 assert_eq!(f.offset(i) + i.len(), f.len());
1110 }
1111 _ => panic!("wrong return type in offset test for oct_digit"),
1112 }
1113 }
1114
1115 #[test]
1116 fn is_not_line_ending_bytes() {
1117 let a: &[u8] = b"ab12cd\nefgh";
1118 assert_eq!(
1119 not_line_ending::<_, (_, ErrorKind)>(a),
1120 Ok((&b"\nefgh"[..], &b"ab12cd"[..]))
1121 );
1122
1123 let b: &[u8] = b"ab12cd\nefgh\nijkl";
1124 assert_eq!(
1125 not_line_ending::<_, (_, ErrorKind)>(b),
1126 Ok((&b"\nefgh\nijkl"[..], &b"ab12cd"[..]))
1127 );
1128
1129 let c: &[u8] = b"ab12cd\r\nefgh\nijkl";
1130 assert_eq!(
1131 not_line_ending::<_, (_, ErrorKind)>(c),
1132 Ok((&b"\r\nefgh\nijkl"[..], &b"ab12cd"[..]))
1133 );
1134
1135 let d: &[u8] = b"ab12cd";
1136 assert_eq!(
1137 not_line_ending::<_, (_, ErrorKind)>(d),
1138 Ok((&[][..], &d[..]))
1139 );
1140 }
1141
1142 #[test]
1143 fn is_not_line_ending_str() {
1144 let f = "βèƒôřè\rÂßÇáƒƭèř";
1162 assert_eq!(not_line_ending(f), Err(Err::Error((f, ErrorKind::Tag))));
1163
1164 let g2: &str = "ab12cd";
1165 assert_eq!(not_line_ending::<_, (_, ErrorKind)>(g2), Ok(("", g2)));
1166 }
1167
1168 #[test]
1169 fn hex_digit_test() {
1170 let i = &b"0123456789abcdefABCDEF;"[..];
1171 assert_parse!(hex_digit1(i), Ok((&b";"[..], &i[..i.len() - 1])));
1172
1173 let i = &b"g"[..];
1174 assert_parse!(
1175 hex_digit1(i),
1176 Err(Err::Error(error_position!(i, ErrorKind::HexDigit)))
1177 );
1178
1179 let i = &b"G"[..];
1180 assert_parse!(
1181 hex_digit1(i),
1182 Err(Err::Error(error_position!(i, ErrorKind::HexDigit)))
1183 );
1184
1185 assert!(AsChar::is_hex_digit(b'0'));
1186 assert!(AsChar::is_hex_digit(b'9'));
1187 assert!(AsChar::is_hex_digit(b'a'));
1188 assert!(AsChar::is_hex_digit(b'f'));
1189 assert!(AsChar::is_hex_digit(b'A'));
1190 assert!(AsChar::is_hex_digit(b'F'));
1191 assert!(!AsChar::is_hex_digit(b'g'));
1192 assert!(!AsChar::is_hex_digit(b'G'));
1193 assert!(!AsChar::is_hex_digit(b'/'));
1194 assert!(!AsChar::is_hex_digit(b':'));
1195 assert!(!AsChar::is_hex_digit(b'@'));
1196 assert!(!AsChar::is_hex_digit(b'\x60'));
1197 }
1198
1199 #[test]
1200 fn oct_digit_test() {
1201 let i = &b"01234567;"[..];
1202 assert_parse!(oct_digit1(i), Ok((&b";"[..], &i[..i.len() - 1])));
1203
1204 let i = &b"8"[..];
1205 assert_parse!(
1206 oct_digit1(i),
1207 Err(Err::Error(error_position!(i, ErrorKind::OctDigit)))
1208 );
1209
1210 assert!(AsChar::is_oct_digit(b'0'));
1211 assert!(AsChar::is_oct_digit(b'7'));
1212 assert!(!AsChar::is_oct_digit(b'8'));
1213 assert!(!AsChar::is_oct_digit(b'9'));
1214 assert!(!AsChar::is_oct_digit(b'a'));
1215 assert!(!AsChar::is_oct_digit(b'A'));
1216 assert!(!AsChar::is_oct_digit(b'/'));
1217 assert!(!AsChar::is_oct_digit(b':'));
1218 assert!(!AsChar::is_oct_digit(b'@'));
1219 assert!(!AsChar::is_oct_digit(b'\x60'));
1220 }
1221
1222 #[test]
1223 fn full_line_windows() {
1224 use crate::sequence::pair;
1225 fn take_full_line(i: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
1226 pair(not_line_ending, line_ending)(i)
1227 }
1228 let input = b"abc\r\n";
1229 let output = take_full_line(input);
1230 assert_eq!(output, Ok((&b""[..], (&b"abc"[..], &b"\r\n"[..]))));
1231 }
1232
1233 #[test]
1234 fn full_line_unix() {
1235 use crate::sequence::pair;
1236 fn take_full_line(i: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
1237 pair(not_line_ending, line_ending)(i)
1238 }
1239 let input = b"abc\n";
1240 let output = take_full_line(input);
1241 assert_eq!(output, Ok((&b""[..], (&b"abc"[..], &b"\n"[..]))));
1242 }
1243
1244 #[test]
1245 fn check_windows_lineending() {
1246 let input = b"\r\n";
1247 let output = line_ending(&input[..]);
1248 assert_parse!(output, Ok((&b""[..], &b"\r\n"[..])));
1249 }
1250
1251 #[test]
1252 fn check_unix_lineending() {
1253 let input = b"\n";
1254 let output = line_ending(&input[..]);
1255 assert_parse!(output, Ok((&b""[..], &b"\n"[..])));
1256 }
1257
1258 #[test]
1259 fn cr_lf() {
1260 assert_parse!(crlf(&b"\r\na"[..]), Ok((&b"a"[..], &b"\r\n"[..])));
1261 assert_parse!(
1262 crlf(&b"\r"[..]),
1263 Err(Err::Error(error_position!(&b"\r"[..], ErrorKind::CrLf)))
1264 );
1265 assert_parse!(
1266 crlf(&b"\ra"[..]),
1267 Err(Err::Error(error_position!(&b"\ra"[..], ErrorKind::CrLf)))
1268 );
1269
1270 assert_parse!(crlf("\r\na"), Ok(("a", "\r\n")));
1271 assert_parse!(
1272 crlf("\r"),
1273 Err(Err::Error(error_position!(&"\r"[..], ErrorKind::CrLf)))
1274 );
1275 assert_parse!(
1276 crlf("\ra"),
1277 Err(Err::Error(error_position!("\ra", ErrorKind::CrLf)))
1278 );
1279 }
1280
1281 #[test]
1282 fn end_of_line() {
1283 assert_parse!(line_ending(&b"\na"[..]), Ok((&b"a"[..], &b"\n"[..])));
1284 assert_parse!(line_ending(&b"\r\na"[..]), Ok((&b"a"[..], &b"\r\n"[..])));
1285 assert_parse!(
1286 line_ending(&b"\r"[..]),
1287 Err(Err::Error(error_position!(&b"\r"[..], ErrorKind::CrLf)))
1288 );
1289 assert_parse!(
1290 line_ending(&b"\ra"[..]),
1291 Err(Err::Error(error_position!(&b"\ra"[..], ErrorKind::CrLf)))
1292 );
1293
1294 assert_parse!(line_ending("\na"), Ok(("a", "\n")));
1295 assert_parse!(line_ending("\r\na"), Ok(("a", "\r\n")));
1296 assert_parse!(
1297 line_ending("\r"),
1298 Err(Err::Error(error_position!(&"\r"[..], ErrorKind::CrLf)))
1299 );
1300 assert_parse!(
1301 line_ending("\ra"),
1302 Err(Err::Error(error_position!("\ra", ErrorKind::CrLf)))
1303 );
1304 }
1305
1306 fn digit_to_i16(input: &str) -> IResult<&str, i16> {
1307 let i = input;
1308 let (i, opt_sign) = opt(alt((char('+'), char('-'))))(i)?;
1309 let sign = match opt_sign {
1310 Some('+') => true,
1311 Some('-') => false,
1312 _ => true,
1313 };
1314
1315 let (i, s) = match digit1::<_, crate::error::Error<_>>(i) {
1316 Ok((i, s)) => (i, s),
1317 Err(_) => {
1318 return Err(Err::Error(crate::error::Error::from_error_kind(
1319 input,
1320 ErrorKind::Digit,
1321 )))
1322 }
1323 };
1324
1325 match s.parse_to() {
1326 Some(n) => {
1327 if sign {
1328 Ok((i, n))
1329 } else {
1330 Ok((i, -n))
1331 }
1332 }
1333 None => Err(Err::Error(crate::error::Error::from_error_kind(
1334 i,
1335 ErrorKind::Digit,
1336 ))),
1337 }
1338 }
1339
1340 fn digit_to_u32(i: &str) -> IResult<&str, u32> {
1341 let (i, s) = digit1(i)?;
1342 match s.parse_to() {
1343 Some(n) => Ok((i, n)),
1344 None => Err(Err::Error(crate::error::Error::from_error_kind(
1345 i,
1346 ErrorKind::Digit,
1347 ))),
1348 }
1349 }
1350
1351 proptest! {
1352 #[test]
1353 fn ints(s in "\\PC*") {
1354 let res1 = digit_to_i16(&s);
1355 let res2 = i16(s.as_str());
1356 assert_eq!(res1, res2);
1357 }
1358
1359 #[test]
1360 fn uints(s in "\\PC*") {
1361 let res1 = digit_to_u32(&s);
1362 let res2 = u32(s.as_str());
1363 assert_eq!(res1, res2);
1364 }
1365 }
1366}