1use crate::branch::alt;
4use crate::bytes::complete::tag;
5use crate::character::complete::{char, digit1, sign};
6use crate::combinator::{cut, map, opt, recognize};
7use crate::error::ParseError;
8use crate::error::{make_error, ErrorKind};
9use crate::internal::*;
10use crate::lib::std::ops::{Range, RangeFrom, RangeTo};
11use crate::sequence::{pair, tuple};
12use crate::traits::{
13 AsBytes, AsChar, Compare, InputIter, InputLength, InputTake, InputTakeAtPosition, Offset, Slice,
14};
15
16#[inline]
32pub fn be_u8<I, E: ParseError<I>>(input: I) -> IResult<I, u8, E>
33where
34 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
35{
36 let bound: usize = 1;
37 if input.input_len() < bound {
38 Err(Err::Error(make_error(input, ErrorKind::Eof)))
39 } else {
40 let res = input.iter_elements().next().unwrap();
41
42 Ok((input.slice(bound..), res))
43 }
44}
45
46#[inline]
62pub fn be_u16<I, E: ParseError<I>>(input: I) -> IResult<I, u16, E>
63where
64 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
65{
66 let bound: usize = 2;
67 if input.input_len() < bound {
68 Err(Err::Error(make_error(input, ErrorKind::Eof)))
69 } else {
70 let mut res = 0u16;
71 for byte in input.iter_elements().take(bound) {
72 res = (res << 8) + byte as u16;
73 }
74
75 Ok((input.slice(bound..), res))
76 }
77}
78
79#[inline]
95pub fn be_u24<I, E: ParseError<I>>(input: I) -> IResult<I, u32, E>
96where
97 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
98{
99 let bound: usize = 3;
100 if input.input_len() < bound {
101 Err(Err::Error(make_error(input, ErrorKind::Eof)))
102 } else {
103 let mut res = 0u32;
104 for byte in input.iter_elements().take(bound) {
105 res = (res << 8) + byte as u32;
106 }
107
108 Ok((input.slice(bound..), res))
109 }
110}
111
112#[inline]
128pub fn be_u32<I, E: ParseError<I>>(input: I) -> IResult<I, u32, E>
129where
130 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
131{
132 let bound: usize = 4;
133 if input.input_len() < bound {
134 Err(Err::Error(make_error(input, ErrorKind::Eof)))
135 } else {
136 let mut res = 0u32;
137 for byte in input.iter_elements().take(bound) {
138 res = (res << 8) + byte as u32;
139 }
140
141 Ok((input.slice(bound..), res))
142 }
143}
144
145#[inline]
161pub fn be_u64<I, E: ParseError<I>>(input: I) -> IResult<I, u64, E>
162where
163 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
164{
165 let bound: usize = 8;
166 if input.input_len() < bound {
167 Err(Err::Error(make_error(input, ErrorKind::Eof)))
168 } else {
169 let mut res = 0u64;
170 for byte in input.iter_elements().take(bound) {
171 res = (res << 8) + byte as u64;
172 }
173
174 Ok((input.slice(bound..), res))
175 }
176}
177
178#[inline]
194pub fn be_u128<I, E: ParseError<I>>(input: I) -> IResult<I, u128, E>
195where
196 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
197{
198 let bound: usize = 16;
199 if input.input_len() < bound {
200 Err(Err::Error(make_error(input, ErrorKind::Eof)))
201 } else {
202 let mut res = 0u128;
203 for byte in input.iter_elements().take(bound) {
204 res = (res << 8) + byte as u128;
205 }
206
207 Ok((input.slice(bound..), res))
208 }
209}
210
211#[inline]
227pub fn be_i8<I, E: ParseError<I>>(input: I) -> IResult<I, i8, E>
228where
229 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
230{
231 be_u8.map(|x| x as i8).parse(input)
232}
233
234#[inline]
250pub fn be_i16<I, E: ParseError<I>>(input: I) -> IResult<I, i16, E>
251where
252 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
253{
254 be_u16.map(|x| x as i16).parse(input)
255}
256
257#[inline]
273pub fn be_i24<I, E: ParseError<I>>(input: I) -> IResult<I, i32, E>
274where
275 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
276{
277 be_u24
279 .map(|x| {
280 if x & 0x80_00_00 != 0 {
281 (x | 0xff_00_00_00) as i32
282 } else {
283 x as i32
284 }
285 })
286 .parse(input)
287}
288
289#[inline]
305pub fn be_i32<I, E: ParseError<I>>(input: I) -> IResult<I, i32, E>
306where
307 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
308{
309 be_u32.map(|x| x as i32).parse(input)
310}
311
312#[inline]
328pub fn be_i64<I, E: ParseError<I>>(input: I) -> IResult<I, i64, E>
329where
330 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
331{
332 be_u64.map(|x| x as i64).parse(input)
333}
334
335#[inline]
351pub fn be_i128<I, E: ParseError<I>>(input: I) -> IResult<I, i128, E>
352where
353 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
354{
355 be_u128.map(|x| x as i128).parse(input)
356}
357
358#[inline]
374pub fn le_u8<I, E: ParseError<I>>(input: I) -> IResult<I, u8, E>
375where
376 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
377{
378 let bound: usize = 1;
379 if input.input_len() < bound {
380 Err(Err::Error(make_error(input, ErrorKind::Eof)))
381 } else {
382 let res = input.iter_elements().next().unwrap();
383
384 Ok((input.slice(bound..), res))
385 }
386}
387
388#[inline]
404pub fn le_u16<I, E: ParseError<I>>(input: I) -> IResult<I, u16, E>
405where
406 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
407{
408 let bound: usize = 2;
409 if input.input_len() < bound {
410 Err(Err::Error(make_error(input, ErrorKind::Eof)))
411 } else {
412 let mut res = 0u16;
413 for (index, byte) in input.iter_indices().take(bound) {
414 res += (byte as u16) << (8 * index);
415 }
416
417 Ok((input.slice(bound..), res))
418 }
419}
420
421#[inline]
437pub fn le_u24<I, E: ParseError<I>>(input: I) -> IResult<I, u32, E>
438where
439 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
440{
441 let bound: usize = 3;
442 if input.input_len() < bound {
443 Err(Err::Error(make_error(input, ErrorKind::Eof)))
444 } else {
445 let mut res = 0u32;
446 for (index, byte) in input.iter_indices().take(bound) {
447 res += (byte as u32) << (8 * index);
448 }
449
450 Ok((input.slice(bound..), res))
451 }
452}
453
454#[inline]
470pub fn le_u32<I, E: ParseError<I>>(input: I) -> IResult<I, u32, E>
471where
472 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
473{
474 let bound: usize = 4;
475 if input.input_len() < bound {
476 Err(Err::Error(make_error(input, ErrorKind::Eof)))
477 } else {
478 let mut res = 0u32;
479 for (index, byte) in input.iter_indices().take(bound) {
480 res += (byte as u32) << (8 * index);
481 }
482
483 Ok((input.slice(bound..), res))
484 }
485}
486
487#[inline]
503pub fn le_u64<I, E: ParseError<I>>(input: I) -> IResult<I, u64, E>
504where
505 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
506{
507 let bound: usize = 8;
508 if input.input_len() < bound {
509 Err(Err::Error(make_error(input, ErrorKind::Eof)))
510 } else {
511 let mut res = 0u64;
512 for (index, byte) in input.iter_indices().take(bound) {
513 res += (byte as u64) << (8 * index);
514 }
515
516 Ok((input.slice(bound..), res))
517 }
518}
519
520#[inline]
536pub fn le_u128<I, E: ParseError<I>>(input: I) -> IResult<I, u128, E>
537where
538 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
539{
540 let bound: usize = 16;
541 if input.input_len() < bound {
542 Err(Err::Error(make_error(input, ErrorKind::Eof)))
543 } else {
544 let mut res = 0u128;
545 for (index, byte) in input.iter_indices().take(bound) {
546 res += (byte as u128) << (8 * index);
547 }
548
549 Ok((input.slice(bound..), res))
550 }
551}
552
553#[inline]
569pub fn le_i8<I, E: ParseError<I>>(input: I) -> IResult<I, i8, E>
570where
571 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
572{
573 be_u8.map(|x| x as i8).parse(input)
574}
575
576#[inline]
592pub fn le_i16<I, E: ParseError<I>>(input: I) -> IResult<I, i16, E>
593where
594 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
595{
596 le_u16.map(|x| x as i16).parse(input)
597}
598
599#[inline]
615pub fn le_i24<I, E: ParseError<I>>(input: I) -> IResult<I, i32, E>
616where
617 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
618{
619 le_u24
621 .map(|x| {
622 if x & 0x80_00_00 != 0 {
623 (x | 0xff_00_00_00) as i32
624 } else {
625 x as i32
626 }
627 })
628 .parse(input)
629}
630
631#[inline]
647pub fn le_i32<I, E: ParseError<I>>(input: I) -> IResult<I, i32, E>
648where
649 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
650{
651 le_u32.map(|x| x as i32).parse(input)
652}
653
654#[inline]
670pub fn le_i64<I, E: ParseError<I>>(input: I) -> IResult<I, i64, E>
671where
672 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
673{
674 le_u64.map(|x| x as i64).parse(input)
675}
676
677#[inline]
693pub fn le_i128<I, E: ParseError<I>>(input: I) -> IResult<I, i128, E>
694where
695 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
696{
697 le_u128.map(|x| x as i128).parse(input)
698}
699
700#[inline]
717pub fn u8<I, E: ParseError<I>>(input: I) -> IResult<I, u8, E>
718where
719 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
720{
721 let bound: usize = 1;
722 if input.input_len() < bound {
723 Err(Err::Error(make_error(input, ErrorKind::Eof)))
724 } else {
725 let res = input.iter_elements().next().unwrap();
726
727 Ok((input.slice(bound..), res))
728 }
729}
730
731#[inline]
757pub fn u16<I, E: ParseError<I>>(endian: crate::number::Endianness) -> fn(I) -> IResult<I, u16, E>
758where
759 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
760{
761 match endian {
762 crate::number::Endianness::Big => be_u16,
763 crate::number::Endianness::Little => le_u16,
764 #[cfg(target_endian = "big")]
765 crate::number::Endianness::Native => be_u16,
766 #[cfg(target_endian = "little")]
767 crate::number::Endianness::Native => le_u16,
768 }
769}
770
771#[inline]
796pub fn u24<I, E: ParseError<I>>(endian: crate::number::Endianness) -> fn(I) -> IResult<I, u32, E>
797where
798 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
799{
800 match endian {
801 crate::number::Endianness::Big => be_u24,
802 crate::number::Endianness::Little => le_u24,
803 #[cfg(target_endian = "big")]
804 crate::number::Endianness::Native => be_u24,
805 #[cfg(target_endian = "little")]
806 crate::number::Endianness::Native => le_u24,
807 }
808}
809
810#[inline]
835pub fn u32<I, E: ParseError<I>>(endian: crate::number::Endianness) -> fn(I) -> IResult<I, u32, E>
836where
837 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
838{
839 match endian {
840 crate::number::Endianness::Big => be_u32,
841 crate::number::Endianness::Little => le_u32,
842 #[cfg(target_endian = "big")]
843 crate::number::Endianness::Native => be_u32,
844 #[cfg(target_endian = "little")]
845 crate::number::Endianness::Native => le_u32,
846 }
847}
848
849#[inline]
874pub fn u64<I, E: ParseError<I>>(endian: crate::number::Endianness) -> fn(I) -> IResult<I, u64, E>
875where
876 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
877{
878 match endian {
879 crate::number::Endianness::Big => be_u64,
880 crate::number::Endianness::Little => le_u64,
881 #[cfg(target_endian = "big")]
882 crate::number::Endianness::Native => be_u64,
883 #[cfg(target_endian = "little")]
884 crate::number::Endianness::Native => le_u64,
885 }
886}
887
888#[inline]
913pub fn u128<I, E: ParseError<I>>(endian: crate::number::Endianness) -> fn(I) -> IResult<I, u128, E>
914where
915 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
916{
917 match endian {
918 crate::number::Endianness::Big => be_u128,
919 crate::number::Endianness::Little => le_u128,
920 #[cfg(target_endian = "big")]
921 crate::number::Endianness::Native => be_u128,
922 #[cfg(target_endian = "little")]
923 crate::number::Endianness::Native => le_u128,
924 }
925}
926
927#[inline]
944pub fn i8<I, E: ParseError<I>>(i: I) -> IResult<I, i8, E>
945where
946 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
947{
948 u8.map(|x| x as i8).parse(i)
949}
950
951#[inline]
976pub fn i16<I, E: ParseError<I>>(endian: crate::number::Endianness) -> fn(I) -> IResult<I, i16, E>
977where
978 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
979{
980 match endian {
981 crate::number::Endianness::Big => be_i16,
982 crate::number::Endianness::Little => le_i16,
983 #[cfg(target_endian = "big")]
984 crate::number::Endianness::Native => be_i16,
985 #[cfg(target_endian = "little")]
986 crate::number::Endianness::Native => le_i16,
987 }
988}
989
990#[inline]
1015pub fn i24<I, E: ParseError<I>>(endian: crate::number::Endianness) -> fn(I) -> IResult<I, i32, E>
1016where
1017 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
1018{
1019 match endian {
1020 crate::number::Endianness::Big => be_i24,
1021 crate::number::Endianness::Little => le_i24,
1022 #[cfg(target_endian = "big")]
1023 crate::number::Endianness::Native => be_i24,
1024 #[cfg(target_endian = "little")]
1025 crate::number::Endianness::Native => le_i24,
1026 }
1027}
1028
1029#[inline]
1054pub fn i32<I, E: ParseError<I>>(endian: crate::number::Endianness) -> fn(I) -> IResult<I, i32, E>
1055where
1056 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
1057{
1058 match endian {
1059 crate::number::Endianness::Big => be_i32,
1060 crate::number::Endianness::Little => le_i32,
1061 #[cfg(target_endian = "big")]
1062 crate::number::Endianness::Native => be_i32,
1063 #[cfg(target_endian = "little")]
1064 crate::number::Endianness::Native => le_i32,
1065 }
1066}
1067
1068#[inline]
1093pub fn i64<I, E: ParseError<I>>(endian: crate::number::Endianness) -> fn(I) -> IResult<I, i64, E>
1094where
1095 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
1096{
1097 match endian {
1098 crate::number::Endianness::Big => be_i64,
1099 crate::number::Endianness::Little => le_i64,
1100 #[cfg(target_endian = "big")]
1101 crate::number::Endianness::Native => be_i64,
1102 #[cfg(target_endian = "little")]
1103 crate::number::Endianness::Native => le_i64,
1104 }
1105}
1106
1107#[inline]
1132pub fn i128<I, E: ParseError<I>>(endian: crate::number::Endianness) -> fn(I) -> IResult<I, i128, E>
1133where
1134 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
1135{
1136 match endian {
1137 crate::number::Endianness::Big => be_i128,
1138 crate::number::Endianness::Little => le_i128,
1139 #[cfg(target_endian = "big")]
1140 crate::number::Endianness::Native => be_i128,
1141 #[cfg(target_endian = "little")]
1142 crate::number::Endianness::Native => le_i128,
1143 }
1144}
1145
1146#[inline]
1162pub fn be_f32<I, E: ParseError<I>>(input: I) -> IResult<I, f32, E>
1163where
1164 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
1165{
1166 match be_u32(input) {
1167 Err(e) => Err(e),
1168 Ok((i, o)) => Ok((i, f32::from_bits(o))),
1169 }
1170}
1171
1172#[inline]
1188pub fn be_f64<I, E: ParseError<I>>(input: I) -> IResult<I, f64, E>
1189where
1190 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
1191{
1192 match be_u64(input) {
1193 Err(e) => Err(e),
1194 Ok((i, o)) => Ok((i, f64::from_bits(o))),
1195 }
1196}
1197
1198#[inline]
1214pub fn le_f32<I, E: ParseError<I>>(input: I) -> IResult<I, f32, E>
1215where
1216 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
1217{
1218 match le_u32(input) {
1219 Err(e) => Err(e),
1220 Ok((i, o)) => Ok((i, f32::from_bits(o))),
1221 }
1222}
1223
1224#[inline]
1240pub fn le_f64<I, E: ParseError<I>>(input: I) -> IResult<I, f64, E>
1241where
1242 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
1243{
1244 match le_u64(input) {
1245 Err(e) => Err(e),
1246 Ok((i, o)) => Ok((i, f64::from_bits(o))),
1247 }
1248}
1249
1250#[inline]
1275pub fn f32<I, E: ParseError<I>>(endian: crate::number::Endianness) -> fn(I) -> IResult<I, f32, E>
1276where
1277 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
1278{
1279 match endian {
1280 crate::number::Endianness::Big => be_f32,
1281 crate::number::Endianness::Little => le_f32,
1282 #[cfg(target_endian = "big")]
1283 crate::number::Endianness::Native => be_f32,
1284 #[cfg(target_endian = "little")]
1285 crate::number::Endianness::Native => le_f32,
1286 }
1287}
1288
1289#[inline]
1314pub fn f64<I, E: ParseError<I>>(endian: crate::number::Endianness) -> fn(I) -> IResult<I, f64, E>
1315where
1316 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
1317{
1318 match endian {
1319 crate::number::Endianness::Big => be_f64,
1320 crate::number::Endianness::Little => le_f64,
1321 #[cfg(target_endian = "big")]
1322 crate::number::Endianness::Native => be_f64,
1323 #[cfg(target_endian = "little")]
1324 crate::number::Endianness::Native => le_f64,
1325 }
1326}
1327
1328#[inline]
1345pub fn hex_u32<'a, E: ParseError<&'a [u8]>>(input: &'a [u8]) -> IResult<&'a [u8], u32, E> {
1346 let (i, o) = crate::bytes::complete::is_a(&b"0123456789abcdefABCDEF"[..])(input)?;
1347 let (parsed, remaining) = if o.len() <= 8 {
1349 (o, i)
1350 } else {
1351 (&input[..8], &input[8..])
1352 };
1353
1354 let res = parsed
1355 .iter()
1356 .rev()
1357 .enumerate()
1358 .map(|(k, &v)| {
1359 let digit = v as char;
1360 digit.to_digit(16).unwrap_or(0) << (k * 4)
1361 })
1362 .sum();
1363
1364 Ok((remaining, res))
1365}
1366
1367#[rustfmt::skip]
1386pub fn recognize_float<T, E:ParseError<T>>(input: T) -> IResult<T, T, E>
1387where
1388 T: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
1389 T: Clone + Offset,
1390 T: InputIter,
1391 <T as InputIter>::Item: AsChar,
1392 T: InputTakeAtPosition,
1393 <T as InputTakeAtPosition>::Item: AsChar,
1394{
1395 recognize(
1396 tuple((
1397 opt(alt((char('+'), char('-')))),
1398 alt((
1399 map(tuple((digit1, opt(pair(char('.'), opt(digit1))))), |_| ()),
1400 map(tuple((char('.'), digit1)), |_| ())
1401 )),
1402 opt(tuple((
1403 alt((char('e'), char('E'))),
1404 opt(alt((char('+'), char('-')))),
1405 cut(digit1)
1406 )))
1407 ))
1408 )(input)
1409}
1410
1411#[doc(hidden)]
1413pub fn recognize_float_or_exceptions<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
1414where
1415 T: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
1416 T: Clone + Offset,
1417 T: InputIter + InputTake + Compare<&'static str>,
1418 <T as InputIter>::Item: AsChar,
1419 T: InputTakeAtPosition,
1420 <T as InputTakeAtPosition>::Item: AsChar,
1421{
1422 alt((
1423 |i: T| {
1424 recognize_float::<_, E>(i.clone()).map_err(|e| match e {
1425 crate::Err::Error(_) => crate::Err::Error(E::from_error_kind(i, ErrorKind::Float)),
1426 crate::Err::Failure(_) => crate::Err::Failure(E::from_error_kind(i, ErrorKind::Float)),
1427 crate::Err::Incomplete(needed) => crate::Err::Incomplete(needed),
1428 })
1429 },
1430 |i: T| {
1431 crate::bytes::complete::tag_no_case::<_, _, E>("nan")(i.clone())
1432 .map_err(|_| crate::Err::Error(E::from_error_kind(i, ErrorKind::Float)))
1433 },
1434 |i: T| {
1435 crate::bytes::complete::tag_no_case::<_, _, E>("inf")(i.clone())
1436 .map_err(|_| crate::Err::Error(E::from_error_kind(i, ErrorKind::Float)))
1437 },
1438 |i: T| {
1439 crate::bytes::complete::tag_no_case::<_, _, E>("infinity")(i.clone())
1440 .map_err(|_| crate::Err::Error(E::from_error_kind(i, ErrorKind::Float)))
1441 },
1442 ))(input)
1443}
1444
1445pub fn recognize_float_parts<T, E: ParseError<T>>(input: T) -> IResult<T, (bool, T, T, i32), E>
1453where
1454 T: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>> + Slice<Range<usize>>,
1455 T: Clone + Offset,
1456 T: InputIter + InputTake,
1457 <T as InputIter>::Item: AsChar + Copy,
1458 T: InputTakeAtPosition + InputLength,
1459 <T as InputTakeAtPosition>::Item: AsChar,
1460 T: for<'a> Compare<&'a [u8]>,
1461 T: AsBytes,
1462{
1463 let (i, sign) = sign(input.clone())?;
1464
1465 let (i, zeroes) = match i.as_bytes().iter().position(|c| *c != b'0') {
1467 Some(index) => i.take_split(index),
1468 None => i.take_split(i.input_len()),
1469 };
1470 let (i, mut integer) = match i
1472 .as_bytes()
1473 .iter()
1474 .position(|c| !(*c >= b'0' && *c <= b'9'))
1475 {
1476 Some(index) => i.take_split(index),
1477 None => i.take_split(i.input_len()),
1478 };
1479
1480 if integer.input_len() == 0 && zeroes.input_len() > 0 {
1481 integer = zeroes.slice(zeroes.input_len() - 1..);
1483 }
1484
1485 let (i, opt_dot) = opt(tag(&b"."[..]))(i)?;
1486 let (i, fraction) = if opt_dot.is_none() {
1487 let i2 = i.clone();
1488 (i2, i.slice(..0))
1489 } else {
1490 let mut zero_count = 0usize;
1492 let mut position = None;
1493 for (pos, c) in i.as_bytes().iter().enumerate() {
1494 if *c >= b'0' && *c <= b'9' {
1495 if *c == b'0' {
1496 zero_count += 1;
1497 } else {
1498 zero_count = 0;
1499 }
1500 } else {
1501 position = Some(pos);
1502 break;
1503 }
1504 }
1505
1506 let position = position.unwrap_or(i.input_len());
1507
1508 let index = if zero_count == 0 {
1509 position
1510 } else if zero_count == position {
1511 position - zero_count + 1
1512 } else {
1513 position - zero_count
1514 };
1515
1516 (i.slice(position..), i.slice(..index))
1517 };
1518
1519 if integer.input_len() == 0 && fraction.input_len() == 0 {
1520 return Err(Err::Error(E::from_error_kind(input, ErrorKind::Float)));
1521 }
1522
1523 let i2 = i.clone();
1524 let (i, e) = match i.as_bytes().iter().next() {
1525 Some(b'e') => (i.slice(1..), true),
1526 Some(b'E') => (i.slice(1..), true),
1527 _ => (i, false),
1528 };
1529
1530 let (i, exp) = if e {
1531 cut(crate::character::complete::i32)(i)?
1532 } else {
1533 (i2, 0)
1534 };
1535
1536 Ok((i, (sign, integer, fraction, exp)))
1537}
1538
1539use crate::traits::ParseTo;
1540
1541pub fn float<T, E: ParseError<T>>(input: T) -> IResult<T, f32, E>
1559where
1560 T: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>> + Slice<Range<usize>>,
1561 T: Clone + Offset + ParseTo<f32> + Compare<&'static str>,
1562 T: InputIter + InputLength + InputTake,
1563 <T as InputIter>::Item: AsChar + Copy,
1564 <T as InputIter>::IterElem: Clone,
1565 T: InputTakeAtPosition,
1566 <T as InputTakeAtPosition>::Item: AsChar,
1567 T: AsBytes,
1568 T: for<'a> Compare<&'a [u8]>,
1569{
1570 let (i, s) = recognize_float_or_exceptions(input)?;
1585 match s.parse_to() {
1586 Some(f) => Ok((i, f)),
1587 None => Err(crate::Err::Error(E::from_error_kind(
1588 i,
1589 crate::error::ErrorKind::Float,
1590 ))),
1591 }
1592}
1593
1594pub fn double<T, E: ParseError<T>>(input: T) -> IResult<T, f64, E>
1612where
1613 T: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>> + Slice<Range<usize>>,
1614 T: Clone + Offset + ParseTo<f64> + Compare<&'static str>,
1615 T: InputIter + InputLength + InputTake,
1616 <T as InputIter>::Item: AsChar + Copy,
1617 <T as InputIter>::IterElem: Clone,
1618 T: InputTakeAtPosition,
1619 <T as InputTakeAtPosition>::Item: AsChar,
1620 T: AsBytes,
1621 T: for<'a> Compare<&'a [u8]>,
1622{
1623 let (i, s) = recognize_float_or_exceptions(input)?;
1638 match s.parse_to() {
1639 Some(f) => Ok((i, f)),
1640 None => Err(crate::Err::Error(E::from_error_kind(
1641 i,
1642 crate::error::ErrorKind::Float,
1643 ))),
1644 }
1645}
1646
1647#[cfg(test)]
1648mod tests {
1649 use super::*;
1650 use crate::error::ErrorKind;
1651 use crate::internal::Err;
1652 use proptest::prelude::*;
1653
1654 macro_rules! assert_parse(
1655 ($left: expr, $right: expr) => {
1656 let res: $crate::IResult<_, _, (_, ErrorKind)> = $left;
1657 assert_eq!(res, $right);
1658 };
1659 );
1660
1661 #[test]
1662 fn i8_tests() {
1663 assert_parse!(i8(&[0x00][..]), Ok((&b""[..], 0)));
1664 assert_parse!(i8(&[0x7f][..]), Ok((&b""[..], 127)));
1665 assert_parse!(i8(&[0xff][..]), Ok((&b""[..], -1)));
1666 assert_parse!(i8(&[0x80][..]), Ok((&b""[..], -128)));
1667 }
1668
1669 #[test]
1670 fn be_i8_tests() {
1671 assert_parse!(be_i8(&[0x00][..]), Ok((&b""[..], 0)));
1672 assert_parse!(be_i8(&[0x7f][..]), Ok((&b""[..], 127)));
1673 assert_parse!(be_i8(&[0xff][..]), Ok((&b""[..], -1)));
1674 assert_parse!(be_i8(&[0x80][..]), Ok((&b""[..], -128)));
1675 }
1676
1677 #[test]
1678 fn be_i16_tests() {
1679 assert_parse!(be_i16(&[0x00, 0x00][..]), Ok((&b""[..], 0)));
1680 assert_parse!(be_i16(&[0x7f, 0xff][..]), Ok((&b""[..], 32_767_i16)));
1681 assert_parse!(be_i16(&[0xff, 0xff][..]), Ok((&b""[..], -1)));
1682 assert_parse!(be_i16(&[0x80, 0x00][..]), Ok((&b""[..], -32_768_i16)));
1683 }
1684
1685 #[test]
1686 fn be_u24_tests() {
1687 assert_parse!(be_u24(&[0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
1688 assert_parse!(be_u24(&[0x00, 0xFF, 0xFF][..]), Ok((&b""[..], 65_535_u32)));
1689 assert_parse!(
1690 be_u24(&[0x12, 0x34, 0x56][..]),
1691 Ok((&b""[..], 1_193_046_u32))
1692 );
1693 }
1694
1695 #[test]
1696 fn be_i24_tests() {
1697 assert_parse!(be_i24(&[0xFF, 0xFF, 0xFF][..]), Ok((&b""[..], -1_i32)));
1698 assert_parse!(be_i24(&[0xFF, 0x00, 0x00][..]), Ok((&b""[..], -65_536_i32)));
1699 assert_parse!(
1700 be_i24(&[0xED, 0xCB, 0xAA][..]),
1701 Ok((&b""[..], -1_193_046_i32))
1702 );
1703 }
1704
1705 #[test]
1706 fn be_i32_tests() {
1707 assert_parse!(be_i32(&[0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
1708 assert_parse!(
1709 be_i32(&[0x7f, 0xff, 0xff, 0xff][..]),
1710 Ok((&b""[..], 2_147_483_647_i32))
1711 );
1712 assert_parse!(be_i32(&[0xff, 0xff, 0xff, 0xff][..]), Ok((&b""[..], -1)));
1713 assert_parse!(
1714 be_i32(&[0x80, 0x00, 0x00, 0x00][..]),
1715 Ok((&b""[..], -2_147_483_648_i32))
1716 );
1717 }
1718
1719 #[test]
1720 fn be_i64_tests() {
1721 assert_parse!(
1722 be_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
1723 Ok((&b""[..], 0))
1724 );
1725 assert_parse!(
1726 be_i64(&[0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]),
1727 Ok((&b""[..], 9_223_372_036_854_775_807_i64))
1728 );
1729 assert_parse!(
1730 be_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]),
1731 Ok((&b""[..], -1))
1732 );
1733 assert_parse!(
1734 be_i64(&[0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
1735 Ok((&b""[..], -9_223_372_036_854_775_808_i64))
1736 );
1737 }
1738
1739 #[test]
1740 fn be_i128_tests() {
1741 assert_parse!(
1742 be_i128(
1743 &[
1744 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1745 0x00
1746 ][..]
1747 ),
1748 Ok((&b""[..], 0))
1749 );
1750 assert_parse!(
1751 be_i128(
1752 &[
1753 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1754 0xff
1755 ][..]
1756 ),
1757 Ok((
1758 &b""[..],
1759 170_141_183_460_469_231_731_687_303_715_884_105_727_i128
1760 ))
1761 );
1762 assert_parse!(
1763 be_i128(
1764 &[
1765 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1766 0xff
1767 ][..]
1768 ),
1769 Ok((&b""[..], -1))
1770 );
1771 assert_parse!(
1772 be_i128(
1773 &[
1774 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1775 0x00
1776 ][..]
1777 ),
1778 Ok((
1779 &b""[..],
1780 -170_141_183_460_469_231_731_687_303_715_884_105_728_i128
1781 ))
1782 );
1783 }
1784
1785 #[test]
1786 fn le_i8_tests() {
1787 assert_parse!(le_i8(&[0x00][..]), Ok((&b""[..], 0)));
1788 assert_parse!(le_i8(&[0x7f][..]), Ok((&b""[..], 127)));
1789 assert_parse!(le_i8(&[0xff][..]), Ok((&b""[..], -1)));
1790 assert_parse!(le_i8(&[0x80][..]), Ok((&b""[..], -128)));
1791 }
1792
1793 #[test]
1794 fn le_i16_tests() {
1795 assert_parse!(le_i16(&[0x00, 0x00][..]), Ok((&b""[..], 0)));
1796 assert_parse!(le_i16(&[0xff, 0x7f][..]), Ok((&b""[..], 32_767_i16)));
1797 assert_parse!(le_i16(&[0xff, 0xff][..]), Ok((&b""[..], -1)));
1798 assert_parse!(le_i16(&[0x00, 0x80][..]), Ok((&b""[..], -32_768_i16)));
1799 }
1800
1801 #[test]
1802 fn le_u24_tests() {
1803 assert_parse!(le_u24(&[0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
1804 assert_parse!(le_u24(&[0xFF, 0xFF, 0x00][..]), Ok((&b""[..], 65_535_u32)));
1805 assert_parse!(
1806 le_u24(&[0x56, 0x34, 0x12][..]),
1807 Ok((&b""[..], 1_193_046_u32))
1808 );
1809 }
1810
1811 #[test]
1812 fn le_i24_tests() {
1813 assert_parse!(le_i24(&[0xFF, 0xFF, 0xFF][..]), Ok((&b""[..], -1_i32)));
1814 assert_parse!(le_i24(&[0x00, 0x00, 0xFF][..]), Ok((&b""[..], -65_536_i32)));
1815 assert_parse!(
1816 le_i24(&[0xAA, 0xCB, 0xED][..]),
1817 Ok((&b""[..], -1_193_046_i32))
1818 );
1819 }
1820
1821 #[test]
1822 fn le_i32_tests() {
1823 assert_parse!(le_i32(&[0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0)));
1824 assert_parse!(
1825 le_i32(&[0xff, 0xff, 0xff, 0x7f][..]),
1826 Ok((&b""[..], 2_147_483_647_i32))
1827 );
1828 assert_parse!(le_i32(&[0xff, 0xff, 0xff, 0xff][..]), Ok((&b""[..], -1)));
1829 assert_parse!(
1830 le_i32(&[0x00, 0x00, 0x00, 0x80][..]),
1831 Ok((&b""[..], -2_147_483_648_i32))
1832 );
1833 }
1834
1835 #[test]
1836 fn le_i64_tests() {
1837 assert_parse!(
1838 le_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
1839 Ok((&b""[..], 0))
1840 );
1841 assert_parse!(
1842 le_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f][..]),
1843 Ok((&b""[..], 9_223_372_036_854_775_807_i64))
1844 );
1845 assert_parse!(
1846 le_i64(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff][..]),
1847 Ok((&b""[..], -1))
1848 );
1849 assert_parse!(
1850 le_i64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80][..]),
1851 Ok((&b""[..], -9_223_372_036_854_775_808_i64))
1852 );
1853 }
1854
1855 #[test]
1856 fn le_i128_tests() {
1857 assert_parse!(
1858 le_i128(
1859 &[
1860 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1861 0x00
1862 ][..]
1863 ),
1864 Ok((&b""[..], 0))
1865 );
1866 assert_parse!(
1867 le_i128(
1868 &[
1869 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1870 0x7f
1871 ][..]
1872 ),
1873 Ok((
1874 &b""[..],
1875 170_141_183_460_469_231_731_687_303_715_884_105_727_i128
1876 ))
1877 );
1878 assert_parse!(
1879 le_i128(
1880 &[
1881 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1882 0xff
1883 ][..]
1884 ),
1885 Ok((&b""[..], -1))
1886 );
1887 assert_parse!(
1888 le_i128(
1889 &[
1890 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1891 0x80
1892 ][..]
1893 ),
1894 Ok((
1895 &b""[..],
1896 -170_141_183_460_469_231_731_687_303_715_884_105_728_i128
1897 ))
1898 );
1899 }
1900
1901 #[test]
1902 fn be_f32_tests() {
1903 assert_parse!(be_f32(&[0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0_f32)));
1904 assert_parse!(
1905 be_f32(&[0x4d, 0x31, 0x1f, 0xd8][..]),
1906 Ok((&b""[..], 185_728_392_f32))
1907 );
1908 }
1909
1910 #[test]
1911 fn be_f64_tests() {
1912 assert_parse!(
1913 be_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
1914 Ok((&b""[..], 0_f64))
1915 );
1916 assert_parse!(
1917 be_f64(&[0x41, 0xa6, 0x23, 0xfb, 0x10, 0x00, 0x00, 0x00][..]),
1918 Ok((&b""[..], 185_728_392_f64))
1919 );
1920 }
1921
1922 #[test]
1923 fn le_f32_tests() {
1924 assert_parse!(le_f32(&[0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 0_f32)));
1925 assert_parse!(
1926 le_f32(&[0xd8, 0x1f, 0x31, 0x4d][..]),
1927 Ok((&b""[..], 185_728_392_f32))
1928 );
1929 }
1930
1931 #[test]
1932 fn le_f64_tests() {
1933 assert_parse!(
1934 le_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]),
1935 Ok((&b""[..], 0_f64))
1936 );
1937 assert_parse!(
1938 le_f64(&[0x00, 0x00, 0x00, 0x10, 0xfb, 0x23, 0xa6, 0x41][..]),
1939 Ok((&b""[..], 185_728_392_f64))
1940 );
1941 }
1942
1943 #[test]
1944 fn hex_u32_tests() {
1945 assert_parse!(
1946 hex_u32(&b";"[..]),
1947 Err(Err::Error(error_position!(&b";"[..], ErrorKind::IsA)))
1948 );
1949 assert_parse!(hex_u32(&b"ff;"[..]), Ok((&b";"[..], 255)));
1950 assert_parse!(hex_u32(&b"1be2;"[..]), Ok((&b";"[..], 7138)));
1951 assert_parse!(hex_u32(&b"c5a31be2;"[..]), Ok((&b";"[..], 3_315_801_058)));
1952 assert_parse!(hex_u32(&b"C5A31be2;"[..]), Ok((&b";"[..], 3_315_801_058)));
1953 assert_parse!(hex_u32(&b"00c5a31be2;"[..]), Ok((&b"e2;"[..], 12_952_347)));
1954 assert_parse!(
1955 hex_u32(&b"c5a31be201;"[..]),
1956 Ok((&b"01;"[..], 3_315_801_058))
1957 );
1958 assert_parse!(hex_u32(&b"ffffffff;"[..]), Ok((&b";"[..], 4_294_967_295)));
1959 assert_parse!(hex_u32(&b"0x1be2;"[..]), Ok((&b"x1be2;"[..], 0)));
1960 assert_parse!(hex_u32(&b"12af"[..]), Ok((&b""[..], 0x12af)));
1961 }
1962
1963 #[test]
1964 #[cfg(feature = "std")]
1965 fn float_test() {
1966 let mut test_cases = vec![
1967 "+3.14",
1968 "3.14",
1969 "-3.14",
1970 "0",
1971 "0.0",
1972 "1.",
1973 ".789",
1974 "-.5",
1975 "1e7",
1976 "-1E-7",
1977 ".3e-2",
1978 "1.e4",
1979 "1.2e4",
1980 "12.34",
1981 "-1.234E-12",
1982 "-1.234e-12",
1983 "0.00000000000000000087",
1984 ];
1985
1986 for test in test_cases.drain(..) {
1987 let expected32 = str::parse::<f32>(test).unwrap();
1988 let expected64 = str::parse::<f64>(test).unwrap();
1989
1990 println!("now parsing: {} -> {}", test, expected32);
1991
1992 let larger = format!("{}", test);
1993 assert_parse!(recognize_float(&larger[..]), Ok(("", test)));
1994
1995 assert_parse!(float(larger.as_bytes()), Ok((&b""[..], expected32)));
1996 assert_parse!(float(&larger[..]), Ok(("", expected32)));
1997
1998 assert_parse!(double(larger.as_bytes()), Ok((&b""[..], expected64)));
1999 assert_parse!(double(&larger[..]), Ok(("", expected64)));
2000 }
2001
2002 let remaining_exponent = "-1.234E-";
2003 assert_parse!(
2004 recognize_float(remaining_exponent),
2005 Err(Err::Failure(("", ErrorKind::Digit)))
2006 );
2007
2008 let (_i, nan) = float::<_, ()>("NaN").unwrap();
2009 assert!(nan.is_nan());
2010
2011 let (_i, inf) = float::<_, ()>("inf").unwrap();
2012 assert!(inf.is_infinite());
2013 let (_i, inf) = float::<_, ()>("infinite").unwrap();
2014 assert!(inf.is_infinite());
2015 }
2016
2017 #[test]
2018 fn configurable_endianness() {
2019 use crate::number::Endianness;
2020
2021 fn be_tst16(i: &[u8]) -> IResult<&[u8], u16> {
2022 u16(Endianness::Big)(i)
2023 }
2024 fn le_tst16(i: &[u8]) -> IResult<&[u8], u16> {
2025 u16(Endianness::Little)(i)
2026 }
2027 assert_eq!(be_tst16(&[0x80, 0x00]), Ok((&b""[..], 32_768_u16)));
2028 assert_eq!(le_tst16(&[0x80, 0x00]), Ok((&b""[..], 128_u16)));
2029
2030 fn be_tst32(i: &[u8]) -> IResult<&[u8], u32> {
2031 u32(Endianness::Big)(i)
2032 }
2033 fn le_tst32(i: &[u8]) -> IResult<&[u8], u32> {
2034 u32(Endianness::Little)(i)
2035 }
2036 assert_eq!(
2037 be_tst32(&[0x12, 0x00, 0x60, 0x00]),
2038 Ok((&b""[..], 302_014_464_u32))
2039 );
2040 assert_eq!(
2041 le_tst32(&[0x12, 0x00, 0x60, 0x00]),
2042 Ok((&b""[..], 6_291_474_u32))
2043 );
2044
2045 fn be_tst64(i: &[u8]) -> IResult<&[u8], u64> {
2046 u64(Endianness::Big)(i)
2047 }
2048 fn le_tst64(i: &[u8]) -> IResult<&[u8], u64> {
2049 u64(Endianness::Little)(i)
2050 }
2051 assert_eq!(
2052 be_tst64(&[0x12, 0x00, 0x60, 0x00, 0x12, 0x00, 0x80, 0x00]),
2053 Ok((&b""[..], 1_297_142_246_100_992_000_u64))
2054 );
2055 assert_eq!(
2056 le_tst64(&[0x12, 0x00, 0x60, 0x00, 0x12, 0x00, 0x80, 0x00]),
2057 Ok((&b""[..], 36_028_874_334_666_770_u64))
2058 );
2059
2060 fn be_tsti16(i: &[u8]) -> IResult<&[u8], i16> {
2061 i16(Endianness::Big)(i)
2062 }
2063 fn le_tsti16(i: &[u8]) -> IResult<&[u8], i16> {
2064 i16(Endianness::Little)(i)
2065 }
2066 assert_eq!(be_tsti16(&[0x00, 0x80]), Ok((&b""[..], 128_i16)));
2067 assert_eq!(le_tsti16(&[0x00, 0x80]), Ok((&b""[..], -32_768_i16)));
2068
2069 fn be_tsti32(i: &[u8]) -> IResult<&[u8], i32> {
2070 i32(Endianness::Big)(i)
2071 }
2072 fn le_tsti32(i: &[u8]) -> IResult<&[u8], i32> {
2073 i32(Endianness::Little)(i)
2074 }
2075 assert_eq!(
2076 be_tsti32(&[0x00, 0x12, 0x60, 0x00]),
2077 Ok((&b""[..], 1_204_224_i32))
2078 );
2079 assert_eq!(
2080 le_tsti32(&[0x00, 0x12, 0x60, 0x00]),
2081 Ok((&b""[..], 6_296_064_i32))
2082 );
2083
2084 fn be_tsti64(i: &[u8]) -> IResult<&[u8], i64> {
2085 i64(Endianness::Big)(i)
2086 }
2087 fn le_tsti64(i: &[u8]) -> IResult<&[u8], i64> {
2088 i64(Endianness::Little)(i)
2089 }
2090 assert_eq!(
2091 be_tsti64(&[0x00, 0xFF, 0x60, 0x00, 0x12, 0x00, 0x80, 0x00]),
2092 Ok((&b""[..], 71_881_672_479_506_432_i64))
2093 );
2094 assert_eq!(
2095 le_tsti64(&[0x00, 0xFF, 0x60, 0x00, 0x12, 0x00, 0x80, 0x00]),
2096 Ok((&b""[..], 36_028_874_334_732_032_i64))
2097 );
2098 }
2099
2100 #[cfg(feature = "std")]
2101 fn parse_f64(i: &str) -> IResult<&str, f64, ()> {
2102 match recognize_float_or_exceptions(i) {
2103 Err(e) => Err(e),
2104 Ok((i, s)) => {
2105 if s.is_empty() {
2106 return Err(Err::Error(()));
2107 }
2108 match s.parse_to() {
2109 Some(n) => Ok((i, n)),
2110 None => Err(Err::Error(())),
2111 }
2112 }
2113 }
2114 }
2115
2116 proptest! {
2117 #[test]
2118 #[cfg(feature = "std")]
2119 fn floats(s in "\\PC*") {
2120 println!("testing {}", s);
2121 let res1 = parse_f64(&s);
2122 let res2 = double::<_, ()>(s.as_str());
2123 assert_eq!(res1, res2);
2124 }
2125 }
2126}