1 //! Algorithms to consume digits and digit separators.
2 //!
3 //! # Complexity
4 //!
5 //! Although superficially quite simple, the level of complexity
6 //! introduced by digit separators can be quite complex, due
7 //! the number of permutations during parsing.
8 //!
9 //! We can consume any combinations of of [0,3] items from the following set:
10 //!     - [l]eading digit separators, where digit separators occur before digits.
11 //!     - [i]nternal digit separators, where digit separators occur between digits.
12 //!     - [t]railing digit separators, where digit separators occur after digits.
13 //!
14 //! In addition to those combinations, we can also have:
15 //!     - [c]onsecutive digit separators, which allows two digit separators to be adjacent.
16 //!
17 //! # Shorthand
18 //!
19 //! We will use the term consumer to denote a function that consumes digits,
20 //! splitting an input buffer at an index, where the leading section contains
21 //! valid input digits, and the trailing section contains invalid characters.
22 //! Due to the number of combinations for consumers, we use the following
23 //! shorthand to denote consumers:
24 //!     - `no`, does not use a digit separator.
25 //!     - `l`, consumes leading digit separators.
26 //!     - `i`, consumes internal digit separators.
27 //!     - `t`, consumes trailing digit separators.
28 //!     - `c`, consumes consecutive digit separators.
29 //!
30 //! Consumers are named `consume_digits_x_separator`, where `x` represents
31 //! the shorthand name of the consumer, in sorted order. For example,
32 //! `consume_digits_ilt` means that consumer can consume
33 //! internal, leading, and trailing digit separators, but not
34 //! consecutive ones.
35 //!
36 //! # Signature
37 //!
38 //! All low-level consumers have the following signature:
39 //!
40 //! ```text
41 //! fn consumer<'a>(
42 //!     digits: &'a [u8],
43 //!     radix: u32,
44 //!     digit_separator: u8
45 //! ) -> (&'a [u8], &'a [u8]);
46 //! ```
47 //!
48 //! All high-level consumers have the following signature:
49 //!
50 //! ```text
51 //! fn consumer<'a>(
52 //!     digits: &'a [u8],
53 //!     radix: u32,
54 //!     format: NumberFormat
55 //! ) -> (&'a [u8], &'a [u8]);
56 //! ```
57 //!
58 //! If the consumer does not require a digit separator, that value is
59 //! simply ignored.
60 
61 use super::format::*;
62 
63 // HELPERS
64 
65 // Convert radix to value.
66 macro_rules! to_digit {
67     ($c:expr, $radix:expr) => (($c as char).to_digit($radix));
68 }
69 
70 // Convert character to digit.
71 #[inline(always)]
is_digit(c: u8, radix: u32) -> bool72 fn is_digit(c: u8, radix: u32) -> bool {
73     to_digit!(c, radix).is_some()
74 }
75 
76 // Convert character to digit.
77 #[cfg(feature = "format")]
78 #[inline(always)]
is_digit_or_separator(c: u8, radix: u32, digit_separator: u8) -> bool79 fn is_digit_or_separator(c: u8, radix: u32, digit_separator: u8) -> bool {
80     return is_digit(c, radix) || c == digit_separator
81 }
82 
83 // Split buffer at index.
84 #[inline(always)]
split_at_index<'a>(digits: &'a [u8], index: usize) -> (&'a [u8], &'a [u8])85 fn split_at_index<'a>(digits: &'a [u8], index: usize)
86     -> (&'a [u8], &'a [u8])
87 {
88     (&digits[..index], &digits[index..])
89 }
90 
91 // CONSUMERS
92 
93 // We use the following convention to denote consumers:
94 //  consume_digits_x, where `x` can be:
95 //      - , does not use a digit separator.
96 //      - l, consumes leading digit separators.
97 //      - i, consumes internal digit separators.
98 //      - t, consumes trailing digit separators.
99 //      - c, consumes consecutive digit separators.
100 //
101 // It then can use any permutation of [lit], with an optional [c] for
102 // each permutation, or use `` for no permutation.
103 
104 // Consume until a an invalid digit is found.
105 // Does not consume any digit separators.
106 #[inline]
consume_digits<'a>(digits: &'a [u8], radix: u32, _: u8) -> (&'a [u8], &'a [u8])107 fn consume_digits<'a>(digits: &'a [u8], radix: u32, _: u8)
108     -> (&'a [u8], &'a [u8])
109 {
110     // Consume all digits.
111     let mut index = 0;
112     while index < digits.len() && is_digit(index!(digits[index]), radix) {
113         index += 1;
114     }
115     split_at_index(digits, index)
116 }
117 
118 // Consume until a an invalid digit is found.
119 // Consumes internal digit separators.
120 #[inline]
121 #[cfg(feature = "format")]
consume_digits_i<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8])122 pub(crate) fn consume_digits_i<'a>(digits: &'a [u8], radix: u32, digit_separator: u8)
123     -> (&'a [u8], &'a [u8])
124 {
125     // Consume all digits and internal digit separators, except for
126     // consecutive digit separators.
127     let mut previous = false;
128     let mut index = 0;
129     while index < digits.len() {
130         let c = index!(digits[index]);
131         if is_digit(c, radix) {
132             index += 1;
133             previous = false;
134         } else if c == digit_separator && index != 0 && !previous {
135             index += 1;
136             previous = true;
137         } else {
138             break;
139         }
140     }
141 
142     // We've gone too far if:
143     //      1). The last character was a digit separator.
144     if previous {
145         index -= 1;
146     }
147 
148     split_at_index(digits, index)
149 }
150 
151 // Consume until a an invalid digit is found.
152 // Consumes internal and consecutive digit separators.
153 #[inline]
154 #[cfg(feature = "format")]
consume_digits_ic<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8])155 pub(crate) fn consume_digits_ic<'a>(digits: &'a [u8], radix: u32, digit_separator: u8)
156     -> (&'a [u8], &'a [u8])
157 {
158     // Consume all characters that are digits or digit separators, except
159     // for a leading digit separator.
160     let mut index = 0;
161     while index < digits.len() {
162         let c = index!(digits[index]);
163         if is_digit(c, radix) {
164             index += 1;
165         } else if c == digit_separator && index != 0 {
166             index += 1;
167         } else {
168             break;
169         }
170     }
171 
172     // We've gone too far if:
173     //      1). The trailing digits are digit separators.
174     // Preconditions:
175     //      1). If index > 0, we know digits[0] has to a digit.
176     while index > 1 && index!(digits[index-1]) == digit_separator {
177         index -= 1;
178     }
179 
180     split_at_index(digits, index)
181 }
182 
183 // Consume until a an invalid digit is found.
184 // Consumes leading digit separators.
185 #[inline]
186 #[cfg(feature = "format")]
consume_digits_l<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8])187 pub(crate) fn consume_digits_l<'a>(digits: &'a [u8], radix: u32, digit_separator: u8)
188     -> (&'a [u8], &'a [u8])
189 {
190     // Consume leading digit separator, if applicable.
191     let mut index = 0;
192     if index < digits.len() && index!(digits[index]) == digit_separator {
193         index += 1;
194     }
195 
196     // Consume all interior digits.
197     // Store the previous index to later determine if any digits
198     // were consumed.
199     let prev_index = index;
200     while index < digits.len() && is_digit(index!(digits[index]), radix) {
201         index += 1;
202     }
203 
204     // We've gone too far if:
205     //      1). We consumed no interior digits.
206     //      2). The next character is a digit separator (cannot be a digit).
207     if prev_index == index && index < digits.len() && index!(digits[index]) == digit_separator {
208         index = 0;
209     }
210 
211     split_at_index(digits, index)
212 }
213 
214 // Consume until a an invalid digit is found.
215 // Consumes leading and consecutive digit separators.
216 #[inline]
217 #[cfg(feature = "format")]
consume_digits_lc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8])218 pub(crate) fn consume_digits_lc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8)
219     -> (&'a [u8], &'a [u8])
220 {
221     // Consume all leading digit separators, if applicable.
222     let mut index = 0;
223     while index < digits.len() && index!(digits[index]) == digit_separator {
224         index += 1;
225     }
226 
227     // Consume all interior digits.
228     while index < digits.len() && is_digit(index!(digits[index]), radix) {
229         index += 1;
230     }
231 
232     // We cannot have gone too far, because in order to be in an invalid
233     // state, we would have to consume 0 digits and the next character
234     // be a digit separator, which is impossible since we greedily
235     // consume leading digit separators.
236 
237     split_at_index(digits, index)
238 }
239 
240 // Consume until a an invalid digit is found.
241 // Consumes trailing digit separators.
242 #[inline]
243 #[cfg(feature = "format")]
consume_digits_t<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8])244 pub(crate) fn consume_digits_t<'a>(digits: &'a [u8], radix: u32, digit_separator: u8)
245     -> (&'a [u8], &'a [u8])
246 {
247     // Consume all interior digits.
248     let mut index = 0;
249     while index < digits.len() && is_digit(index!(digits[index]), radix) {
250         index += 1;
251     }
252 
253     // Consume a trailing digit separator, if applicable.
254     // Store the previous index to later determine if a digit separator
255     // was consumed.
256     let prev_index = index;
257     if index < digits.len() && index!(digits[index]) == digit_separator {
258         index += 1;
259     }
260 
261     // We have gone too far if:
262     //      1). We consumed a trailing digit separator.
263     //      2). The next character is a digit or digit separator.
264     if index != prev_index && index < digits.len() && is_digit_or_separator(index!(digits[index]), radix, digit_separator) {
265         index = prev_index;
266     }
267 
268     split_at_index(digits, index)
269 }
270 
271 // Consume until a an invalid digit is found.
272 // Consumes trailing and consecutive digit separators.
273 #[inline]
274 #[cfg(feature = "format")]
consume_digits_tc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8])275 pub(crate) fn consume_digits_tc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8)
276     -> (&'a [u8], &'a [u8])
277 {
278     // Consume all interior digits.
279     let mut index = 0;
280     while index < digits.len() && is_digit(index!(digits[index]), radix) {
281         index += 1;
282     }
283 
284     // Consume all trailing digit separators, if applicable.
285     // Store the previous index to later determine if any digit
286     // separators were consumed.
287     let prev_index = index;
288     while index < digits.len() && index!(digits[index]) == digit_separator {
289         index += 1;
290     }
291 
292     // We have gone too far if:
293     //      1). We consumed more than 1 trailing digit separators.
294     //      2). The next character is a digit (cannot be a digit separator).
295     if index != prev_index && index < digits.len() && is_digit(index!(digits[index]), radix) {
296         index = prev_index;
297     }
298 
299     split_at_index(digits, index)
300 }
301 
302 // Consume until a an invalid digit is found.
303 // Consumes leading and internal digit separators.
304 #[inline]
305 #[cfg(feature = "format")]
consume_digits_il<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8])306 pub(crate) fn consume_digits_il<'a>(digits: &'a [u8], radix: u32, digit_separator: u8)
307     -> (&'a [u8], &'a [u8])
308 {
309     // Consume digits and digit separators, until consecutive digit
310     // separators or invalid characters.
311     let mut previous = false;
312     let mut index = 0;
313     while index < digits.len() {
314         let c = index!(digits[index]);
315         if is_digit(c, radix) {
316             index += 1;
317             previous = false;
318         } else if c == digit_separator && !previous {
319             index += 1;
320             previous = true;
321         } else {
322             break;
323         }
324     }
325 
326     // We've taken everything except consecutive digit separators.
327     // We've gone too far if:
328     //      1). The last index was a digit separator unless:
329     //          1). The current index is 1 (index 0 was a digit separator).
330     //          2). The current character is not a digit separator (cannot be a digit).
331     if previous && !(index == 1 && index < digits.len() && index!(digits[index]) != digit_separator) {
332         index -= 1;
333     }
334 
335     split_at_index(digits, index)
336 }
337 
338 // Consume until a an invalid digit is found.
339 // Consumes leading and internal digit separators.
340 #[inline]
341 #[cfg(feature = "format")]
consume_digits_ilc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8])342 pub(crate) fn consume_digits_ilc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8)
343     -> (&'a [u8], &'a [u8])
344 {
345     // Consume digits and digit separators until an invalid character.
346     let mut index = 0;
347     while index < digits.len() {
348         let c = index!(digits[index]);
349         if is_digit_or_separator(c, radix, digit_separator) {
350             index += 1;
351         } else {
352             break;
353         }
354     }
355 
356     // We've taken everything except invalid characters.
357     // We have gone too far if:
358     //      1). We have trailing digit separators.
359     // Remove all trailing digit separators, however, store the index in
360     // case all are removed.
361     let current_index = index;
362     while index >= 1 && index!(digits[index-1]) == digit_separator {
363         index -= 1;
364     }
365 
366     // All trailing digit separators were removed (or current_index is 0).
367     // Reset back to current index.
368     if index == 0 {
369         index = current_index;
370     }
371 
372     split_at_index(digits, index)
373 }
374 
375 // Consume until a an invalid digit is found.
376 // Consumes internal and trailing digit separators.
377 #[inline]
378 #[cfg(feature = "format")]
consume_digits_it<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8])379 pub(crate) fn consume_digits_it<'a>(digits: &'a [u8], radix: u32, digit_separator: u8)
380     -> (&'a [u8], &'a [u8])
381 {
382     // Consume all characters that are digits or digit separators, except
383     // leading and consecutive digit separators.
384     let mut previous = false;
385     let mut index = 0;
386     while index < digits.len() {
387         let c = index!(digits[index]);
388         if is_digit(c, radix) {
389             index += 1;
390             previous = false;
391         } else if c == digit_separator && index != 0 && !previous {
392             index += 1;
393             previous = true;
394         } else {
395             break;
396         }
397     }
398 
399     // We needed the check for `index != 0` to ensure we don't consume
400     // buffers like b"_123_". However, We might not have gotten a
401     // trailing separator if:
402     //      1). The index was 0, something like b"_.".
403     if index == 0 && index < digits.len() && index!(digits[index]) == digit_separator {
404         index += 1;
405         previous = true;
406     }
407 
408     // We've taken up to 1 leading digit separator, or anything
409     // except consecutive digit separators. We've gone too far if:
410     //      1). We take consecutive digit separators.
411     //      2). The next character is a digit (only occurs from special index == 9 check).
412     if previous && index < digits.len() && is_digit_or_separator(index!(digits[index]), radix, digit_separator) {
413         index -= 1;
414     }
415 
416     split_at_index(digits, index)
417 }
418 
419 // Consume until a an invalid digit is found.
420 // Consumes internal, trailing, and consecutive digit separators.
421 #[inline]
422 #[cfg(feature = "format")]
consume_digits_itc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8])423 pub(crate) fn consume_digits_itc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8)
424     -> (&'a [u8], &'a [u8])
425 {
426     // Consume all characters that are digits or digit separators, except
427     // for a leading digit separator.
428     let mut index = 0;
429     while index < digits.len() {
430         let c = index!(digits[index]);
431         if is_digit(c, radix) {
432             index += 1;
433         } else if c == digit_separator && index != 0 {
434             index += 1;
435         } else {
436             break;
437         }
438     }
439 
440     // We needed to check for `index != 0` to ensure we don't consume
441     // buffers like b"_123_". However, We might not have gotten a
442     // trailing separator if:
443     //      1). The index was 0, something like b"_." or b"__.".
444     if index == 0 {
445         // Consume all leading digit separators.
446         while index < digits.len() && index!(digits[index]) == digit_separator {
447             index += 1;
448         }
449 
450         // Now, we might have gone too far. If the next character is a digit,
451         // we need to rollback to 0.
452         if index < digits.len() && is_digit(index!(digits[index]), radix) {
453             index = 0;
454         }
455     }
456 
457     split_at_index(digits, index)
458 }
459 
460 // Consume until a an invalid digit is found.
461 // Consumes leading and trailing digit separators.
462 #[inline]
463 #[cfg(feature = "format")]
consume_digits_lt<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8])464 pub(crate) fn consume_digits_lt<'a>(digits: &'a [u8], radix: u32, digit_separator: u8)
465     -> (&'a [u8], &'a [u8])
466 {
467     // Consume leading digit separator, if applicable.
468     let mut index = 0;
469     if index < digits.len() && index!(digits[index]) == digit_separator {
470         index += 1;
471     }
472 
473     // Consume all interior digits.
474     // Store the previous index to later determine if any digits
475     // were consumed.
476     let prev_index = index;
477     while index < digits.len() && is_digit(index!(digits[index]), radix) {
478         index += 1;
479     }
480 
481     // Consume a trailing digit separator. If we haven't consumed any digits,
482     // then we have a leading b'__', so we shouldn't consume that either.
483     let mut previous = index == prev_index;
484     if !previous && index < digits.len() && index!(digits[index]) == digit_separator {
485         index += 1;
486         previous = true;
487     }
488 
489     // We have gone too far if:
490     //      1). The last character was a digit separator.
491     //      2). The current character is a digit or digit separator.
492     if index < digits.len() && previous && is_digit_or_separator(index!(digits[index]), radix, digit_separator) {
493         index -= 1;
494     }
495 
496     split_at_index(digits, index)
497 }
498 
499 // Consume until a an invalid digit is found.
500 // Consumes leading, trailing, and consecutive digit separators.
501 #[inline]
502 #[cfg(feature = "format")]
consume_digits_ltc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8])503 pub(crate) fn consume_digits_ltc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8)
504     -> (&'a [u8], &'a [u8])
505 {
506     // Consume all leading digit separators, if applicable.
507     let mut index = 0;
508     while index < digits.len() && index!(digits[index]) == digit_separator {
509         index += 1;
510     }
511 
512     // Consume all interior digits.
513     // We don't need to store the index, because if we consume no digits,
514     // then the next character cannot possibly be a digit separator.
515     while index < digits.len() && is_digit(index!(digits[index]), radix) {
516         index += 1;
517     }
518 
519     // Consume all trailing digit separators.
520     let prev_index = index;
521     while index < digits.len() && index!(digits[index]) == digit_separator {
522         index += 1;
523     }
524 
525     // We have gone too far if:
526     //      1). We consumed trailing digit separators.
527     //      2). The subsequent character is a digit (cannot be a digit separator).
528     if index < digits.len() && index != prev_index && is_digit(index!(digits[index]), radix) {
529         index = prev_index;
530     }
531 
532     split_at_index(digits, index)
533 }
534 
535 
536 // Consume until a an invalid digit is found.
537 // Consumes leading, internal, and trailing digit separators.
538 #[inline]
539 #[cfg(feature = "format")]
consume_digits_ilt<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8])540 pub(crate) fn consume_digits_ilt<'a>(digits: &'a [u8], radix: u32, digit_separator: u8)
541     -> (&'a [u8], &'a [u8])
542 {
543     // Consume digits and digit separators, until consecutive digit
544     // separators or invalid characters.
545     let mut previous = false;
546     let mut index = 0;
547     while index < digits.len() {
548         let c = index!(digits[index]);
549         if is_digit(c, radix) {
550             index += 1;
551             previous = false;
552         } else if c == digit_separator && !previous {
553             index += 1;
554             previous = true;
555         } else {
556             break;
557         }
558     }
559 
560     // We've taken everything except consecutive digit separators.
561     // That means we've gone too far if:
562     //      1). The last character was a digit separator.
563     //      2). The current character is a digit separator.
564     if previous && index < digits.len() && index!(digits[index]) == digit_separator {
565         index -= 1;
566     }
567 
568     split_at_index(digits, index)
569 }
570 
571 // Consume until a an invalid digit is found.
572 // Consumes leading, internal, trailing, and consecutive digit separators.
573 #[inline]
574 #[cfg(feature = "format")]
consume_digits_iltc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8) -> (&'a [u8], &'a [u8])575 pub(crate) fn consume_digits_iltc<'a>(digits: &'a [u8], radix: u32, digit_separator: u8)
576     -> (&'a [u8], &'a [u8])
577 {
578     // Consume digits and digit separators, until an invalid character.
579     // There is no post-condition since we accept any digit or
580     // digit separator combination.
581     let mut index = 0;
582     while index < digits.len() {
583         let c = index!(digits[index]);
584         if is_digit_or_separator(c, radix, digit_separator) {
585             index += 1;
586         } else {
587             break;
588         }
589     }
590 
591     split_at_index(digits, index)
592 }
593 
594 // API
595 
596 // Consume digits without a digit separator.
597 #[inline]
consume_digits_no_separator<'a>(bytes: &'a [u8], radix: u32, format: NumberFormat) -> (&'a [u8], &'a [u8])598 pub(crate) fn consume_digits_no_separator<'a>(bytes: &'a [u8], radix: u32, format: NumberFormat)
599     -> (&'a [u8], &'a [u8])
600 {
601     consume_digits(bytes, radix, format.digit_separator())
602 }
603 
604 // Consume digits while ignoring the digit separator.
605 #[inline]
606 #[cfg(feature = "format")]
consume_digits_ignore_separator<'a>(bytes: &'a [u8], radix: u32, format: NumberFormat) -> (&'a [u8], &'a [u8])607 pub(crate) fn consume_digits_ignore_separator<'a>(bytes: &'a [u8], radix: u32, format: NumberFormat)
608     -> (&'a [u8], &'a [u8])
609 {
610     consume_digits_iltc(bytes, radix, format.digit_separator())
611 }
612 
613 // Consume digits with a digit separator in the integer component.
614 #[inline]
615 #[cfg(feature = "format")]
consume_integer_digits_separator<'a>(bytes: &'a [u8], radix: u32, format: NumberFormat) -> (&'a [u8], &'a [u8])616 pub(crate) fn consume_integer_digits_separator<'a>(bytes: &'a [u8], radix: u32, format: NumberFormat)
617     -> (&'a [u8], &'a [u8])
618 {
619     const I: NumberFormat = NumberFormat::INTEGER_INTERNAL_DIGIT_SEPARATOR;
620     const L: NumberFormat = NumberFormat::INTEGER_LEADING_DIGIT_SEPARATOR;
621     const T: NumberFormat = NumberFormat::INTEGER_TRAILING_DIGIT_SEPARATOR;
622     const C: NumberFormat = NumberFormat::INTEGER_CONSECUTIVE_DIGIT_SEPARATOR;
623     const IL: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | L.bits());
624     const IT: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | T.bits());
625     const LT: NumberFormat = NumberFormat::from_bits_truncate(L.bits() | T.bits());
626     const ILT: NumberFormat = NumberFormat::from_bits_truncate(IL.bits() | T.bits());
627     const IC: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | C.bits());
628     const LC: NumberFormat = NumberFormat::from_bits_truncate(L.bits() | C.bits());
629     const TC: NumberFormat = NumberFormat::from_bits_truncate(T.bits() | C.bits());
630     const ILC: NumberFormat = NumberFormat::from_bits_truncate(IL.bits() | C.bits());
631     const ITC: NumberFormat = NumberFormat::from_bits_truncate(IT.bits() | C.bits());
632     const LTC: NumberFormat = NumberFormat::from_bits_truncate(LT.bits() | C.bits());
633     const ILTC: NumberFormat = NumberFormat::from_bits_truncate(ILT.bits() | C.bits());
634 
635     let digit_separator = format.digit_separator();
636     match format & NumberFormat::INTEGER_DIGIT_SEPARATOR_FLAG_MASK {
637         I       => consume_digits_i(bytes, radix, digit_separator),
638         IC      => consume_digits_ic(bytes, radix, digit_separator),
639         L       => consume_digits_l(bytes, radix, digit_separator),
640         LC      => consume_digits_lc(bytes, radix, digit_separator),
641         T       => consume_digits_t(bytes, radix, digit_separator),
642         TC      => consume_digits_tc(bytes, radix, digit_separator),
643         IL      => consume_digits_il(bytes, radix, digit_separator),
644         ILC     => consume_digits_ilc(bytes, radix, digit_separator),
645         IT      => consume_digits_it(bytes, radix, digit_separator),
646         ITC     => consume_digits_itc(bytes, radix, digit_separator),
647         LT      => consume_digits_lt(bytes, radix, digit_separator),
648         LTC     => consume_digits_ltc(bytes, radix, digit_separator),
649         ILT     => consume_digits_ilt(bytes, radix, digit_separator),
650         ILTC    => consume_digits_iltc(bytes, radix, digit_separator),
651         _       => unreachable!()
652     }
653 }
654 
655 // Consume digits with a digit separator in the fraction component.
656 #[inline]
657 #[cfg(feature = "format")]
consume_fraction_digits_separator<'a>(bytes: &'a [u8], radix: u32, format: NumberFormat) -> (&'a [u8], &'a [u8])658 pub(crate) fn consume_fraction_digits_separator<'a>(bytes: &'a [u8], radix: u32, format: NumberFormat)
659     -> (&'a [u8], &'a [u8])
660 {
661     const I: NumberFormat = NumberFormat::FRACTION_INTERNAL_DIGIT_SEPARATOR;
662     const L: NumberFormat = NumberFormat::FRACTION_LEADING_DIGIT_SEPARATOR;
663     const T: NumberFormat = NumberFormat::FRACTION_TRAILING_DIGIT_SEPARATOR;
664     const C: NumberFormat = NumberFormat::FRACTION_CONSECUTIVE_DIGIT_SEPARATOR;
665     const IL: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | L.bits());
666     const IT: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | T.bits());
667     const LT: NumberFormat = NumberFormat::from_bits_truncate(L.bits() | T.bits());
668     const ILT: NumberFormat = NumberFormat::from_bits_truncate(IL.bits() | T.bits());
669     const IC: NumberFormat = NumberFormat::from_bits_truncate(I.bits() | C.bits());
670     const LC: NumberFormat = NumberFormat::from_bits_truncate(L.bits() | C.bits());
671     const TC: NumberFormat = NumberFormat::from_bits_truncate(T.bits() | C.bits());
672     const ILC: NumberFormat = NumberFormat::from_bits_truncate(IL.bits() | C.bits());
673     const ITC: NumberFormat = NumberFormat::from_bits_truncate(IT.bits() | C.bits());
674     const LTC: NumberFormat = NumberFormat::from_bits_truncate(LT.bits() | C.bits());
675     const ILTC: NumberFormat = NumberFormat::from_bits_truncate(ILT.bits() | C.bits());
676 
677     let digit_separator = format.digit_separator();
678     match format & NumberFormat::FRACTION_DIGIT_SEPARATOR_FLAG_MASK {
679         I       => consume_digits_i(bytes, radix, digit_separator),
680         IC      => consume_digits_ic(bytes, radix, digit_separator),
681         L       => consume_digits_l(bytes, radix, digit_separator),
682         LC      => consume_digits_lc(bytes, radix, digit_separator),
683         T       => consume_digits_t(bytes, radix, digit_separator),
684         TC      => consume_digits_tc(bytes, radix, digit_separator),
685         IL      => consume_digits_il(bytes, radix, digit_separator),
686         ILC     => consume_digits_ilc(bytes, radix, digit_separator),
687         IT      => consume_digits_it(bytes, radix, digit_separator),
688         ITC     => consume_digits_itc(bytes, radix, digit_separator),
689         LT      => consume_digits_lt(bytes, radix, digit_separator),
690         LTC     => consume_digits_ltc(bytes, radix, digit_separator),
691         ILT     => consume_digits_ilt(bytes, radix, digit_separator),
692         ILTC    => consume_digits_iltc(bytes, radix, digit_separator),
693         _       => unreachable!()
694     }
695 }
696 
697 // TESTS
698 // -----
699 
700 #[cfg(test)]
701 mod tests {
702     use super::*;
703 
704     #[test]
consume_digits_test()705     fn consume_digits_test() {
706         assert_eq!(consume_digits(b!("123.45"), 10, b'_'), (b!("123"), b!(".45")));
707         assert_eq!(consume_digits(b!("1e45"), 10, b'_'), (b!("1"), b!("e45")));
708         assert_eq!(consume_digits(b!("1e"), 10, b'_'), (b!("1"), b!("e")));
709         assert_eq!(consume_digits(b!("1"), 10, b'_'), (b!("1"), b!("")));
710         assert_eq!(consume_digits(b!("_45"), 10, b'_'), (b!(""), b!("_45")));
711         assert_eq!(consume_digits(b!("__45"), 10, b'_'), (b!(""), b!("__45")));
712         assert_eq!(consume_digits(b!("_.45"), 10, b'_'), (b!(""), b!("_.45")));
713         assert_eq!(consume_digits(b!("__.45"), 10, b'_'), (b!(""), b!("__.45")));
714         assert_eq!(consume_digits(b!("4_5"), 10, b'_'), (b!("4"), b!("_5")));
715         assert_eq!(consume_digits(b!("4__5"), 10, b'_'), (b!("4"), b!("__5")));
716         assert_eq!(consume_digits(b!("4_"), 10, b'_'), (b!("4"), b!("_")));
717         assert_eq!(consume_digits(b!("4__"), 10, b'_'), (b!("4"), b!("__")));
718         assert_eq!(consume_digits(b!("4_."), 10, b'_'), (b!("4"), b!("_.")));
719         assert_eq!(consume_digits(b!("4__."), 10, b'_'), (b!("4"), b!("__.")));
720         assert_eq!(consume_digits(b!("_45_5"), 10, b'_'), (b!(""), b!("_45_5")));
721         assert_eq!(consume_digits(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5")));
722         assert_eq!(consume_digits(b!("_.45_5"), 10, b'_'), (b!(""), b!("_.45_5")));
723         assert_eq!(consume_digits(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5")));
724         assert_eq!(consume_digits(b!("4_5_"), 10, b'_'), (b!("4"), b!("_5_")));
725         assert_eq!(consume_digits(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__")));
726         assert_eq!(consume_digits(b!("4_5_.5"), 10, b'_'), (b!("4"), b!("_5_.5")));
727         assert_eq!(consume_digits(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5")));
728         assert_eq!(consume_digits(b!("_45_"), 10, b'_'), (b!(""), b!("_45_")));
729         assert_eq!(consume_digits(b!("__45__"), 10, b'_'), (b!(""), b!("__45__")));
730         assert_eq!(consume_digits(b!("_45_.56"), 10, b'_'), (b!(""), b!("_45_.56")));
731         assert_eq!(consume_digits(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56")));
732         assert_eq!(consume_digits(b!("_4_5_"), 10, b'_'), (b!(""), b!("_4_5_")));
733         assert_eq!(consume_digits(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__")));
734         assert_eq!(consume_digits(b!("_4_5_.56"), 10, b'_'), (b!(""), b!("_4_5_.56")));
735         assert_eq!(consume_digits(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56")));
736     }
737 
738     #[cfg(feature = "format")]
739     #[test]
consume_digits_l_test()740     fn consume_digits_l_test() {
741         assert_eq!(consume_digits_l(b!("123.45"), 10, b'_'), (b!("123"), b!(".45")));
742         assert_eq!(consume_digits_l(b!("1e45"), 10, b'_'), (b!("1"), b!("e45")));
743         assert_eq!(consume_digits_l(b!("1e"), 10, b'_'), (b!("1"), b!("e")));
744         assert_eq!(consume_digits_l(b!("1"), 10, b'_'), (b!("1"), b!("")));
745         assert_eq!(consume_digits_l(b!("_45"), 10, b'_'), (b!("_45"), b!("")));
746         assert_eq!(consume_digits_l(b!("__45"), 10, b'_'), (b!(""), b!("__45")));
747         assert_eq!(consume_digits_l(b!("_.45"), 10, b'_'), (b!("_"), b!(".45")));
748         assert_eq!(consume_digits_l(b!("__.45"), 10, b'_'), (b!(""), b!("__.45")));
749         assert_eq!(consume_digits_l(b!("4_5"), 10, b'_'), (b!("4"), b!("_5")));
750         assert_eq!(consume_digits_l(b!("4__5"), 10, b'_'), (b!("4"), b!("__5")));
751         assert_eq!(consume_digits_l(b!("4_"), 10, b'_'), (b!("4"), b!("_")));
752         assert_eq!(consume_digits_l(b!("4__"), 10, b'_'), (b!("4"), b!("__")));
753         assert_eq!(consume_digits_l(b!("4_."), 10, b'_'), (b!("4"), b!("_.")));
754         assert_eq!(consume_digits_l(b!("4__."), 10, b'_'), (b!("4"), b!("__.")));
755         assert_eq!(consume_digits_l(b!("_45_5"), 10, b'_'), (b!("_45"), b!("_5")));
756         assert_eq!(consume_digits_l(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5")));
757         assert_eq!(consume_digits_l(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5")));
758         assert_eq!(consume_digits_l(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5")));
759         assert_eq!(consume_digits_l(b!("4_5_"), 10, b'_'), (b!("4"), b!("_5_")));
760         assert_eq!(consume_digits_l(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__")));
761         assert_eq!(consume_digits_l(b!("4_5_.5"), 10, b'_'), (b!("4"), b!("_5_.5")));
762         assert_eq!(consume_digits_l(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5")));
763         assert_eq!(consume_digits_l(b!("_45_"), 10, b'_'), (b!("_45"), b!("_")));
764         assert_eq!(consume_digits_l(b!("__45__"), 10, b'_'), (b!(""), b!("__45__")));
765         assert_eq!(consume_digits_l(b!("_45_.56"), 10, b'_'), (b!("_45"), b!("_.56")));
766         assert_eq!(consume_digits_l(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56")));
767         assert_eq!(consume_digits_l(b!("_4_5_"), 10, b'_'), (b!("_4"), b!("_5_")));
768         assert_eq!(consume_digits_l(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__")));
769         assert_eq!(consume_digits_l(b!("_4_5_.56"), 10, b'_'), (b!("_4"), b!("_5_.56")));
770         assert_eq!(consume_digits_l(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56")));
771 
772         assert_eq!(consume_digits_lc(b!("123.45"), 10, b'_'), (b!("123"), b!(".45")));
773         assert_eq!(consume_digits_lc(b!("1e45"), 10, b'_'), (b!("1"), b!("e45")));
774         assert_eq!(consume_digits_lc(b!("1e"), 10, b'_'), (b!("1"), b!("e")));
775         assert_eq!(consume_digits_lc(b!("1"), 10, b'_'), (b!("1"), b!("")));
776         assert_eq!(consume_digits_lc(b!("_45"), 10, b'_'), (b!("_45"), b!("")));
777         assert_eq!(consume_digits_lc(b!("__45"), 10, b'_'), (b!("__45"), b!("")));
778         assert_eq!(consume_digits_lc(b!("_.45"), 10, b'_'), (b!("_"), b!(".45")));
779         assert_eq!(consume_digits_lc(b!("__.45"), 10, b'_'), (b!("__"), b!(".45")));
780         assert_eq!(consume_digits_lc(b!("4_5"), 10, b'_'), (b!("4"), b!("_5")));
781         assert_eq!(consume_digits_lc(b!("4__5"), 10, b'_'), (b!("4"), b!("__5")));
782         assert_eq!(consume_digits_lc(b!("4_"), 10, b'_'), (b!("4"), b!("_")));
783         assert_eq!(consume_digits_lc(b!("4__"), 10, b'_'), (b!("4"), b!("__")));
784         assert_eq!(consume_digits_lc(b!("4_."), 10, b'_'), (b!("4"), b!("_.")));
785         assert_eq!(consume_digits_lc(b!("4__."), 10, b'_'), (b!("4"), b!("__.")));
786         assert_eq!(consume_digits_lc(b!("_45_5"), 10, b'_'), (b!("_45"), b!("_5")));
787         assert_eq!(consume_digits_lc(b!("__45__5"), 10, b'_'), (b!("__45"), b!("__5")));
788         assert_eq!(consume_digits_lc(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5")));
789         assert_eq!(consume_digits_lc(b!("__.45__5"), 10, b'_'), (b!("__"), b!(".45__5")));
790         assert_eq!(consume_digits_lc(b!("4_5_"), 10, b'_'), (b!("4"), b!("_5_")));
791         assert_eq!(consume_digits_lc(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__")));
792         assert_eq!(consume_digits_lc(b!("4_5_.5"), 10, b'_'), (b!("4"), b!("_5_.5")));
793         assert_eq!(consume_digits_lc(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5")));
794         assert_eq!(consume_digits_lc(b!("_45_"), 10, b'_'), (b!("_45"), b!("_")));
795         assert_eq!(consume_digits_lc(b!("__45__"), 10, b'_'), (b!("__45"), b!("__")));
796         assert_eq!(consume_digits_lc(b!("_45_.56"), 10, b'_'), (b!("_45"), b!("_.56")));
797         assert_eq!(consume_digits_lc(b!("__45__.56"), 10, b'_'), (b!("__45"), b!("__.56")));
798         assert_eq!(consume_digits_lc(b!("_4_5_"), 10, b'_'), (b!("_4"), b!("_5_")));
799         assert_eq!(consume_digits_lc(b!("__4__5__"), 10, b'_'), (b!("__4"), b!("__5__")));
800         assert_eq!(consume_digits_lc(b!("_4_5_.56"), 10, b'_'), (b!("_4"), b!("_5_.56")));
801         assert_eq!(consume_digits_lc(b!("__4__5__.56"), 10, b'_'), (b!("__4"), b!("__5__.56")));
802 
803     }
804 
805     #[cfg(feature = "format")]
806     #[test]
consume_digits_i_test()807     fn consume_digits_i_test() {
808         assert_eq!(consume_digits_i(b!("123.45"), 10, b'_'), (b!("123"), b!(".45")));
809         assert_eq!(consume_digits_i(b!("1e45"), 10, b'_'), (b!("1"), b!("e45")));
810         assert_eq!(consume_digits_i(b!("1e"), 10, b'_'), (b!("1"), b!("e")));
811         assert_eq!(consume_digits_i(b!("1"), 10, b'_'), (b!("1"), b!("")));
812         assert_eq!(consume_digits_i(b!("_45"), 10, b'_'), (b!(""), b!("_45")));
813         assert_eq!(consume_digits_i(b!("__45"), 10, b'_'), (b!(""), b!("__45")));
814         assert_eq!(consume_digits_i(b!("_.45"), 10, b'_'), (b!(""), b!("_.45")));
815         assert_eq!(consume_digits_i(b!("__.45"), 10, b'_'), (b!(""), b!("__.45")));
816         assert_eq!(consume_digits_i(b!("4_5"), 10, b'_'), (b!("4_5"), b!("")));
817         assert_eq!(consume_digits_i(b!("4__5"), 10, b'_'), (b!("4"), b!("__5")));
818         assert_eq!(consume_digits_i(b!("4_"), 10, b'_'), (b!("4"), b!("_")));
819         assert_eq!(consume_digits_i(b!("4__"), 10, b'_'), (b!("4"), b!("__")));
820         assert_eq!(consume_digits_i(b!("4_."), 10, b'_'), (b!("4"), b!("_.")));
821         assert_eq!(consume_digits_i(b!("4__."), 10, b'_'), (b!("4"), b!("__.")));
822         assert_eq!(consume_digits_i(b!("_45_5"), 10, b'_'), (b!(""), b!("_45_5")));
823         assert_eq!(consume_digits_i(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5")));
824         assert_eq!(consume_digits_i(b!("_.45_5"), 10, b'_'), (b!(""), b!("_.45_5")));
825         assert_eq!(consume_digits_i(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5")));
826         assert_eq!(consume_digits_i(b!("4_5_"), 10, b'_'), (b!("4_5"), b!("_")));
827         assert_eq!(consume_digits_i(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__")));
828         assert_eq!(consume_digits_i(b!("4_5_.5"), 10, b'_'), (b!("4_5"), b!("_.5")));
829         assert_eq!(consume_digits_i(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5")));
830         assert_eq!(consume_digits_i(b!("_45_"), 10, b'_'), (b!(""), b!("_45_")));
831         assert_eq!(consume_digits_i(b!("__45__"), 10, b'_'), (b!(""), b!("__45__")));
832         assert_eq!(consume_digits_i(b!("_45_.56"), 10, b'_'), (b!(""), b!("_45_.56")));
833         assert_eq!(consume_digits_i(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56")));
834         assert_eq!(consume_digits_i(b!("_4_5_"), 10, b'_'), (b!(""), b!("_4_5_")));
835         assert_eq!(consume_digits_i(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__")));
836         assert_eq!(consume_digits_i(b!("_4_5_.56"), 10, b'_'), (b!(""), b!("_4_5_.56")));
837         assert_eq!(consume_digits_i(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56")));
838 
839         assert_eq!(consume_digits_ic(b!("123.45"), 10, b'_'), (b!("123"), b!(".45")));
840         assert_eq!(consume_digits_ic(b!("1e45"), 10, b'_'), (b!("1"), b!("e45")));
841         assert_eq!(consume_digits_ic(b!("1e"), 10, b'_'), (b!("1"), b!("e")));
842         assert_eq!(consume_digits_ic(b!("1"), 10, b'_'), (b!("1"), b!("")));
843         assert_eq!(consume_digits_ic(b!("_45"), 10, b'_'), (b!(""), b!("_45")));
844         assert_eq!(consume_digits_ic(b!("__45"), 10, b'_'), (b!(""), b!("__45")));
845         assert_eq!(consume_digits_ic(b!("_.45"), 10, b'_'), (b!(""), b!("_.45")));
846         assert_eq!(consume_digits_ic(b!("__.45"), 10, b'_'), (b!(""), b!("__.45")));
847         assert_eq!(consume_digits_ic(b!("4_5"), 10, b'_'), (b!("4_5"), b!("")));
848         assert_eq!(consume_digits_ic(b!("4__5"), 10, b'_'), (b!("4__5"), b!("")));
849         assert_eq!(consume_digits_ic(b!("4_"), 10, b'_'), (b!("4"), b!("_")));
850         assert_eq!(consume_digits_ic(b!("4__"), 10, b'_'), (b!("4"), b!("__")));
851         assert_eq!(consume_digits_ic(b!("4_."), 10, b'_'), (b!("4"), b!("_.")));
852         assert_eq!(consume_digits_ic(b!("4__."), 10, b'_'), (b!("4"), b!("__.")));
853         assert_eq!(consume_digits_ic(b!("_45_5"), 10, b'_'), (b!(""), b!("_45_5")));
854         assert_eq!(consume_digits_ic(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5")));
855         assert_eq!(consume_digits_ic(b!("_.45_5"), 10, b'_'), (b!(""), b!("_.45_5")));
856         assert_eq!(consume_digits_ic(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5")));
857         assert_eq!(consume_digits_ic(b!("4_5_"), 10, b'_'), (b!("4_5"), b!("_")));
858         assert_eq!(consume_digits_ic(b!("4__5__"), 10, b'_'), (b!("4__5"), b!("__")));
859         assert_eq!(consume_digits_ic(b!("4_5_.5"), 10, b'_'), (b!("4_5"), b!("_.5")));
860         assert_eq!(consume_digits_ic(b!("4__5__.5"), 10, b'_'), (b!("4__5"), b!("__.5")));
861         assert_eq!(consume_digits_ic(b!("_45_"), 10, b'_'), (b!(""), b!("_45_")));
862         assert_eq!(consume_digits_ic(b!("__45__"), 10, b'_'), (b!(""), b!("__45__")));
863         assert_eq!(consume_digits_ic(b!("_45_.56"), 10, b'_'), (b!(""), b!("_45_.56")));
864         assert_eq!(consume_digits_ic(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56")));
865         assert_eq!(consume_digits_ic(b!("_4_5_"), 10, b'_'), (b!(""), b!("_4_5_")));
866         assert_eq!(consume_digits_ic(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__")));
867         assert_eq!(consume_digits_ic(b!("_4_5_.56"), 10, b'_'), (b!(""), b!("_4_5_.56")));
868         assert_eq!(consume_digits_ic(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56")));
869 
870     }
871 
872     #[cfg(feature = "format")]
873     #[test]
consume_digits_t_test()874     fn consume_digits_t_test() {
875         assert_eq!(consume_digits_t(b!("123.45"), 10, b'_'), (b!("123"), b!(".45")));
876         assert_eq!(consume_digits_t(b!("1e45"), 10, b'_'), (b!("1"), b!("e45")));
877         assert_eq!(consume_digits_t(b!("1e"), 10, b'_'), (b!("1"), b!("e")));
878         assert_eq!(consume_digits_t(b!("1"), 10, b'_'), (b!("1"), b!("")));
879         assert_eq!(consume_digits_t(b!("_45"), 10, b'_'), (b!(""), b!("_45")));
880         assert_eq!(consume_digits_t(b!("__45"), 10, b'_'), (b!(""), b!("__45")));
881         assert_eq!(consume_digits_t(b!("_.45"), 10, b'_'), (b!("_"), b!(".45")));
882         assert_eq!(consume_digits_t(b!("__.45"), 10, b'_'), (b!(""), b!("__.45")));
883         assert_eq!(consume_digits_t(b!("4_5"), 10, b'_'), (b!("4"), b!("_5")));
884         assert_eq!(consume_digits_t(b!("4__5"), 10, b'_'), (b!("4"), b!("__5")));
885         assert_eq!(consume_digits_t(b!("4_"), 10, b'_'), (b!("4_"), b!("")));
886         assert_eq!(consume_digits_t(b!("4__"), 10, b'_'), (b!("4"), b!("__")));
887         assert_eq!(consume_digits_t(b!("4_."), 10, b'_'), (b!("4_"), b!(".")));
888         assert_eq!(consume_digits_t(b!("4__."), 10, b'_'), (b!("4"), b!("__.")));
889         assert_eq!(consume_digits_t(b!("_45_5"), 10, b'_'), (b!(""), b!("_45_5")));
890         assert_eq!(consume_digits_t(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5")));
891         assert_eq!(consume_digits_t(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5")));
892         assert_eq!(consume_digits_t(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5")));
893         assert_eq!(consume_digits_t(b!("4_5_"), 10, b'_'), (b!("4"), b!("_5_")));
894         assert_eq!(consume_digits_t(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__")));
895         assert_eq!(consume_digits_t(b!("4_5_.5"), 10, b'_'), (b!("4"), b!("_5_.5")));
896         assert_eq!(consume_digits_t(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5")));
897         assert_eq!(consume_digits_t(b!("_45_"), 10, b'_'), (b!(""), b!("_45_")));
898         assert_eq!(consume_digits_t(b!("__45__"), 10, b'_'), (b!(""), b!("__45__")));
899         assert_eq!(consume_digits_t(b!("_45_.56"), 10, b'_'), (b!(""), b!("_45_.56")));
900         assert_eq!(consume_digits_t(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56")));
901         assert_eq!(consume_digits_t(b!("_4_5_"), 10, b'_'), (b!(""), b!("_4_5_")));
902         assert_eq!(consume_digits_t(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__")));
903         assert_eq!(consume_digits_t(b!("_4_5_.56"), 10, b'_'), (b!(""), b!("_4_5_.56")));
904         assert_eq!(consume_digits_t(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56")));
905 
906         assert_eq!(consume_digits_tc(b!("123.45"), 10, b'_'), (b!("123"), b!(".45")));
907         assert_eq!(consume_digits_tc(b!("1e45"), 10, b'_'), (b!("1"), b!("e45")));
908         assert_eq!(consume_digits_tc(b!("1e"), 10, b'_'), (b!("1"), b!("e")));
909         assert_eq!(consume_digits_tc(b!("1"), 10, b'_'), (b!("1"), b!("")));
910         assert_eq!(consume_digits_tc(b!("_45"), 10, b'_'), (b!(""), b!("_45")));
911         assert_eq!(consume_digits_tc(b!("__45"), 10, b'_'), (b!(""), b!("__45")));
912         assert_eq!(consume_digits_tc(b!("_.45"), 10, b'_'), (b!("_"), b!(".45")));
913         assert_eq!(consume_digits_tc(b!("__.45"), 10, b'_'), (b!("__"), b!(".45")));
914         assert_eq!(consume_digits_tc(b!("4_5"), 10, b'_'), (b!("4"), b!("_5")));
915         assert_eq!(consume_digits_tc(b!("4__5"), 10, b'_'), (b!("4"), b!("__5")));
916         assert_eq!(consume_digits_tc(b!("4_"), 10, b'_'), (b!("4_"), b!("")));
917         assert_eq!(consume_digits_tc(b!("4__"), 10, b'_'), (b!("4__"), b!("")));
918         assert_eq!(consume_digits_tc(b!("4_."), 10, b'_'), (b!("4_"), b!(".")));
919         assert_eq!(consume_digits_tc(b!("4__."), 10, b'_'), (b!("4__"), b!(".")));
920         assert_eq!(consume_digits_tc(b!("_45_5"), 10, b'_'), (b!(""), b!("_45_5")));
921         assert_eq!(consume_digits_tc(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5")));
922         assert_eq!(consume_digits_tc(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5")));
923         assert_eq!(consume_digits_tc(b!("__.45__5"), 10, b'_'), (b!("__"), b!(".45__5")));
924         assert_eq!(consume_digits_tc(b!("4_5_"), 10, b'_'), (b!("4"), b!("_5_")));
925         assert_eq!(consume_digits_tc(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__")));
926         assert_eq!(consume_digits_tc(b!("4_5_.5"), 10, b'_'), (b!("4"), b!("_5_.5")));
927         assert_eq!(consume_digits_tc(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5")));
928         assert_eq!(consume_digits_tc(b!("_45_"), 10, b'_'), (b!(""), b!("_45_")));
929         assert_eq!(consume_digits_tc(b!("__45__"), 10, b'_'), (b!(""), b!("__45__")));
930         assert_eq!(consume_digits_tc(b!("_45_.56"), 10, b'_'), (b!(""), b!("_45_.56")));
931         assert_eq!(consume_digits_tc(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56")));
932         assert_eq!(consume_digits_tc(b!("_4_5_"), 10, b'_'), (b!(""), b!("_4_5_")));
933         assert_eq!(consume_digits_tc(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__")));
934         assert_eq!(consume_digits_tc(b!("_4_5_.56"), 10, b'_'), (b!(""), b!("_4_5_.56")));
935         assert_eq!(consume_digits_tc(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56")));
936     }
937 
938     #[cfg(feature = "format")]
939     #[test]
consume_digits_il_test()940     fn consume_digits_il_test() {
941         assert_eq!(consume_digits_il(b!("123.45"), 10, b'_'), (b!("123"), b!(".45")));
942         assert_eq!(consume_digits_il(b!("1e45"), 10, b'_'), (b!("1"), b!("e45")));
943         assert_eq!(consume_digits_il(b!("1e"), 10, b'_'), (b!("1"), b!("e")));
944         assert_eq!(consume_digits_il(b!("1"), 10, b'_'), (b!("1"), b!("")));
945         assert_eq!(consume_digits_il(b!("_45"), 10, b'_'), (b!("_45"), b!("")));
946         assert_eq!(consume_digits_il(b!("__45"), 10, b'_'), (b!(""), b!("__45")));
947         assert_eq!(consume_digits_il(b!("_.45"), 10, b'_'), (b!("_"), b!(".45")));
948         assert_eq!(consume_digits_il(b!("__.45"), 10, b'_'), (b!(""), b!("__.45")));
949         assert_eq!(consume_digits_il(b!("4_5"), 10, b'_'), (b!("4_5"), b!("")));
950         assert_eq!(consume_digits_il(b!("4__5"), 10, b'_'), (b!("4"), b!("__5")));
951         assert_eq!(consume_digits_il(b!("4_"), 10, b'_'), (b!("4"), b!("_")));
952         assert_eq!(consume_digits_il(b!("4__"), 10, b'_'), (b!("4"), b!("__")));
953         assert_eq!(consume_digits_il(b!("4_."), 10, b'_'), (b!("4"), b!("_.")));
954         assert_eq!(consume_digits_il(b!("4__."), 10, b'_'), (b!("4"), b!("__.")));
955         assert_eq!(consume_digits_il(b!("_45_5"), 10, b'_'), (b!("_45_5"), b!("")));
956         assert_eq!(consume_digits_il(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5")));
957         assert_eq!(consume_digits_il(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5")));
958         assert_eq!(consume_digits_il(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5")));
959         assert_eq!(consume_digits_il(b!("4_5_"), 10, b'_'), (b!("4_5"), b!("_")));
960         assert_eq!(consume_digits_il(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__")));
961         assert_eq!(consume_digits_il(b!("4_5_.5"), 10, b'_'), (b!("4_5"), b!("_.5")));
962         assert_eq!(consume_digits_il(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5")));
963         assert_eq!(consume_digits_il(b!("_45_"), 10, b'_'), (b!("_45"), b!("_")));
964         assert_eq!(consume_digits_il(b!("__45__"), 10, b'_'), (b!(""), b!("__45__")));
965         assert_eq!(consume_digits_il(b!("_45_.56"), 10, b'_'), (b!("_45"), b!("_.56")));
966         assert_eq!(consume_digits_il(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56")));
967         assert_eq!(consume_digits_il(b!("_4_5_"), 10, b'_'), (b!("_4_5"), b!("_")));
968         assert_eq!(consume_digits_il(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__")));
969         assert_eq!(consume_digits_il(b!("_4_5_.56"), 10, b'_'), (b!("_4_5"), b!("_.56")));
970         assert_eq!(consume_digits_il(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56")));
971 
972         assert_eq!(consume_digits_ilc(b!("123.45"), 10, b'_'), (b!("123"), b!(".45")));
973         assert_eq!(consume_digits_ilc(b!("1e45"), 10, b'_'), (b!("1"), b!("e45")));
974         assert_eq!(consume_digits_ilc(b!("1e"), 10, b'_'), (b!("1"), b!("e")));
975         assert_eq!(consume_digits_ilc(b!("1"), 10, b'_'), (b!("1"), b!("")));
976         assert_eq!(consume_digits_ilc(b!("_45"), 10, b'_'), (b!("_45"), b!("")));
977         assert_eq!(consume_digits_ilc(b!("__45"), 10, b'_'), (b!("__45"), b!("")));
978         assert_eq!(consume_digits_ilc(b!("_.45"), 10, b'_'), (b!("_"), b!(".45")));
979         assert_eq!(consume_digits_ilc(b!("__.45"), 10, b'_'), (b!("__"), b!(".45")));
980         assert_eq!(consume_digits_ilc(b!("4_5"), 10, b'_'), (b!("4_5"), b!("")));
981         assert_eq!(consume_digits_ilc(b!("4__5"), 10, b'_'), (b!("4__5"), b!("")));
982         assert_eq!(consume_digits_ilc(b!("4_"), 10, b'_'), (b!("4"), b!("_")));
983         assert_eq!(consume_digits_ilc(b!("4__"), 10, b'_'), (b!("4"), b!("__")));
984         assert_eq!(consume_digits_ilc(b!("4_."), 10, b'_'), (b!("4"), b!("_.")));
985         assert_eq!(consume_digits_ilc(b!("4__."), 10, b'_'), (b!("4"), b!("__.")));
986         assert_eq!(consume_digits_ilc(b!("_45_5"), 10, b'_'), (b!("_45_5"), b!("")));
987         assert_eq!(consume_digits_ilc(b!("__45__5"), 10, b'_'), (b!("__45__5"), b!("")));
988         assert_eq!(consume_digits_ilc(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5")));
989         assert_eq!(consume_digits_ilc(b!("__.45__5"), 10, b'_'), (b!("__"), b!(".45__5")));
990         assert_eq!(consume_digits_ilc(b!("4_5_"), 10, b'_'), (b!("4_5"), b!("_")));
991         assert_eq!(consume_digits_ilc(b!("4__5__"), 10, b'_'), (b!("4__5"), b!("__")));
992         assert_eq!(consume_digits_ilc(b!("4_5_.5"), 10, b'_'), (b!("4_5"), b!("_.5")));
993         assert_eq!(consume_digits_ilc(b!("4__5__.5"), 10, b'_'), (b!("4__5"), b!("__.5")));
994         assert_eq!(consume_digits_ilc(b!("_45_"), 10, b'_'), (b!("_45"), b!("_")));
995         assert_eq!(consume_digits_ilc(b!("__45__"), 10, b'_'), (b!("__45"), b!("__")));
996         assert_eq!(consume_digits_ilc(b!("_45_.56"), 10, b'_'), (b!("_45"), b!("_.56")));
997         assert_eq!(consume_digits_ilc(b!("__45__.56"), 10, b'_'), (b!("__45"), b!("__.56")));
998         assert_eq!(consume_digits_ilc(b!("_4_5_"), 10, b'_'), (b!("_4_5"), b!("_")));
999         assert_eq!(consume_digits_ilc(b!("__4__5__"), 10, b'_'), (b!("__4__5"), b!("__")));
1000         assert_eq!(consume_digits_ilc(b!("_4_5_.56"), 10, b'_'), (b!("_4_5"), b!("_.56")));
1001         assert_eq!(consume_digits_ilc(b!("__4__5__.56"), 10, b'_'), (b!("__4__5"), b!("__.56")));
1002     }
1003 
1004     #[cfg(feature = "format")]
1005     #[test]
consume_digits_it_test()1006     fn consume_digits_it_test() {
1007         assert_eq!(consume_digits_it(b!("123.45"), 10, b'_'), (b!("123"), b!(".45")));
1008         assert_eq!(consume_digits_it(b!("1e45"), 10, b'_'), (b!("1"), b!("e45")));
1009         assert_eq!(consume_digits_it(b!("1e"), 10, b'_'), (b!("1"), b!("e")));
1010         assert_eq!(consume_digits_it(b!("1"), 10, b'_'), (b!("1"), b!("")));
1011         assert_eq!(consume_digits_it(b!("_45"), 10, b'_'), (b!(""), b!("_45")));
1012         assert_eq!(consume_digits_it(b!("__45"), 10, b'_'), (b!(""), b!("__45")));
1013         assert_eq!(consume_digits_it(b!("_.45"), 10, b'_'), (b!("_"), b!(".45")));
1014         assert_eq!(consume_digits_it(b!("__.45"), 10, b'_'), (b!(""), b!("__.45")));
1015         assert_eq!(consume_digits_it(b!("4_5"), 10, b'_'), (b!("4_5"), b!("")));
1016         assert_eq!(consume_digits_it(b!("4__5"), 10, b'_'), (b!("4"), b!("__5")));
1017         assert_eq!(consume_digits_it(b!("4_"), 10, b'_'), (b!("4_"), b!("")));
1018         assert_eq!(consume_digits_it(b!("4__"), 10, b'_'), (b!("4"), b!("__")));
1019         assert_eq!(consume_digits_it(b!("4_."), 10, b'_'), (b!("4_"), b!(".")));
1020         assert_eq!(consume_digits_it(b!("4__."), 10, b'_'), (b!("4"), b!("__.")));
1021         assert_eq!(consume_digits_it(b!("_45_5"), 10, b'_'), (b!(""), b!("_45_5")));
1022         assert_eq!(consume_digits_it(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5")));
1023         assert_eq!(consume_digits_it(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5")));
1024         assert_eq!(consume_digits_it(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5")));
1025         assert_eq!(consume_digits_it(b!("4_5_"), 10, b'_'), (b!("4_5_"), b!("")));
1026         assert_eq!(consume_digits_it(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__")));
1027         assert_eq!(consume_digits_it(b!("4_5_.5"), 10, b'_'), (b!("4_5_"), b!(".5")));
1028         assert_eq!(consume_digits_it(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5")));
1029         assert_eq!(consume_digits_it(b!("_45_"), 10, b'_'), (b!(""), b!("_45_")));
1030         assert_eq!(consume_digits_it(b!("__45__"), 10, b'_'), (b!(""), b!("__45__")));
1031         assert_eq!(consume_digits_it(b!("_45_.56"), 10, b'_'), (b!(""), b!("_45_.56")));
1032         assert_eq!(consume_digits_it(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56")));
1033         assert_eq!(consume_digits_it(b!("_4_5_"), 10, b'_'), (b!(""), b!("_4_5_")));
1034         assert_eq!(consume_digits_it(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__")));
1035         assert_eq!(consume_digits_it(b!("_4_5_.56"), 10, b'_'), (b!(""), b!("_4_5_.56")));
1036         assert_eq!(consume_digits_it(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56")));
1037 
1038         assert_eq!(consume_digits_itc(b!("123.45"), 10, b'_'), (b!("123"), b!(".45")));
1039         assert_eq!(consume_digits_itc(b!("1e45"), 10, b'_'), (b!("1"), b!("e45")));
1040         assert_eq!(consume_digits_itc(b!("1e"), 10, b'_'), (b!("1"), b!("e")));
1041         assert_eq!(consume_digits_itc(b!("1"), 10, b'_'), (b!("1"), b!("")));
1042         assert_eq!(consume_digits_itc(b!("_45"), 10, b'_'), (b!(""), b!("_45")));
1043         assert_eq!(consume_digits_itc(b!("__45"), 10, b'_'), (b!(""), b!("__45")));
1044         assert_eq!(consume_digits_itc(b!("_.45"), 10, b'_'), (b!("_"), b!(".45")));
1045         assert_eq!(consume_digits_itc(b!("__.45"), 10, b'_'), (b!("__"), b!(".45")));
1046         assert_eq!(consume_digits_itc(b!("4_5"), 10, b'_'), (b!("4_5"), b!("")));
1047         assert_eq!(consume_digits_itc(b!("4__5"), 10, b'_'), (b!("4__5"), b!("")));
1048         assert_eq!(consume_digits_itc(b!("4_"), 10, b'_'), (b!("4_"), b!("")));
1049         assert_eq!(consume_digits_itc(b!("4__"), 10, b'_'), (b!("4__"), b!("")));
1050         assert_eq!(consume_digits_itc(b!("4_."), 10, b'_'), (b!("4_"), b!(".")));
1051         assert_eq!(consume_digits_itc(b!("4__."), 10, b'_'), (b!("4__"), b!(".")));
1052         assert_eq!(consume_digits_itc(b!("_45_5"), 10, b'_'), (b!(""), b!("_45_5")));
1053         assert_eq!(consume_digits_itc(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5")));
1054         assert_eq!(consume_digits_itc(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5")));
1055         assert_eq!(consume_digits_itc(b!("__.45__5"), 10, b'_'), (b!("__"), b!(".45__5")));
1056         assert_eq!(consume_digits_itc(b!("4_5_"), 10, b'_'), (b!("4_5_"), b!("")));
1057         assert_eq!(consume_digits_itc(b!("4__5__"), 10, b'_'), (b!("4__5__"), b!("")));
1058         assert_eq!(consume_digits_itc(b!("4_5_.5"), 10, b'_'), (b!("4_5_"), b!(".5")));
1059         assert_eq!(consume_digits_itc(b!("4__5__.5"), 10, b'_'), (b!("4__5__"), b!(".5")));
1060         assert_eq!(consume_digits_itc(b!("_45_"), 10, b'_'), (b!(""), b!("_45_")));
1061         assert_eq!(consume_digits_itc(b!("__45__"), 10, b'_'), (b!(""), b!("__45__")));
1062         assert_eq!(consume_digits_itc(b!("_45_.56"), 10, b'_'), (b!(""), b!("_45_.56")));
1063         assert_eq!(consume_digits_itc(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56")));
1064         assert_eq!(consume_digits_itc(b!("_4_5_"), 10, b'_'), (b!(""), b!("_4_5_")));
1065         assert_eq!(consume_digits_itc(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__")));
1066         assert_eq!(consume_digits_itc(b!("_4_5_.56"), 10, b'_'), (b!(""), b!("_4_5_.56")));
1067         assert_eq!(consume_digits_itc(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56")));
1068     }
1069 
1070     #[cfg(feature = "format")]
1071     #[test]
consume_digits_lt_test()1072     fn consume_digits_lt_test() {
1073         assert_eq!(consume_digits_lt(b!("123.45"), 10, b'_'), (b!("123"), b!(".45")));
1074         assert_eq!(consume_digits_lt(b!("1e45"), 10, b'_'), (b!("1"), b!("e45")));
1075         assert_eq!(consume_digits_lt(b!("1e"), 10, b'_'), (b!("1"), b!("e")));
1076         assert_eq!(consume_digits_lt(b!("1"), 10, b'_'), (b!("1"), b!("")));
1077         assert_eq!(consume_digits_lt(b!("_45"), 10, b'_'), (b!("_45"), b!("")));
1078         assert_eq!(consume_digits_lt(b!("__45"), 10, b'_'), (b!(""), b!("__45")));
1079         assert_eq!(consume_digits_lt(b!("_.45"), 10, b'_'), (b!("_"), b!(".45")));
1080         assert_eq!(consume_digits_lt(b!("__.45"), 10, b'_'), (b!(""), b!("__.45")));
1081         assert_eq!(consume_digits_lt(b!("4_5"), 10, b'_'), (b!("4"), b!("_5")));
1082         assert_eq!(consume_digits_lt(b!("4__5"), 10, b'_'), (b!("4"), b!("__5")));
1083         assert_eq!(consume_digits_lt(b!("4_"), 10, b'_'), (b!("4_"), b!("")));
1084         assert_eq!(consume_digits_lt(b!("4__"), 10, b'_'), (b!("4"), b!("__")));
1085         assert_eq!(consume_digits_lt(b!("4_."), 10, b'_'), (b!("4_"), b!(".")));
1086         assert_eq!(consume_digits_lt(b!("4__."), 10, b'_'), (b!("4"), b!("__.")));
1087         assert_eq!(consume_digits_lt(b!("_45_5"), 10, b'_'), (b!("_45"), b!("_5")));
1088         assert_eq!(consume_digits_lt(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5")));
1089         assert_eq!(consume_digits_lt(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5")));
1090         assert_eq!(consume_digits_lt(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5")));
1091         assert_eq!(consume_digits_lt(b!("4_5_"), 10, b'_'), (b!("4"), b!("_5_")));
1092         assert_eq!(consume_digits_lt(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__")));
1093         assert_eq!(consume_digits_lt(b!("4_5_.5"), 10, b'_'), (b!("4"), b!("_5_.5")));
1094         assert_eq!(consume_digits_lt(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5")));
1095         assert_eq!(consume_digits_lt(b!("_45_"), 10, b'_'), (b!("_45_"), b!("")));
1096         assert_eq!(consume_digits_lt(b!("__45__"), 10, b'_'), (b!(""), b!("__45__")));
1097         assert_eq!(consume_digits_lt(b!("_45_.56"), 10, b'_'), (b!("_45_"), b!(".56")));
1098         assert_eq!(consume_digits_lt(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56")));
1099         assert_eq!(consume_digits_lt(b!("_4_5_"), 10, b'_'), (b!("_4"), b!("_5_")));
1100         assert_eq!(consume_digits_lt(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__")));
1101         assert_eq!(consume_digits_lt(b!("_4_5_.56"), 10, b'_'), (b!("_4"), b!("_5_.56")));
1102         assert_eq!(consume_digits_lt(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56")));
1103 
1104         assert_eq!(consume_digits_ltc(b!("123.45"), 10, b'_'), (b!("123"), b!(".45")));
1105         assert_eq!(consume_digits_ltc(b!("1e45"), 10, b'_'), (b!("1"), b!("e45")));
1106         assert_eq!(consume_digits_ltc(b!("1e"), 10, b'_'), (b!("1"), b!("e")));
1107         assert_eq!(consume_digits_ltc(b!("1"), 10, b'_'), (b!("1"), b!("")));
1108         assert_eq!(consume_digits_ltc(b!("_45"), 10, b'_'), (b!("_45"), b!("")));
1109         assert_eq!(consume_digits_ltc(b!("__45"), 10, b'_'), (b!("__45"), b!("")));
1110         assert_eq!(consume_digits_ltc(b!("_.45"), 10, b'_'), (b!("_"), b!(".45")));
1111         assert_eq!(consume_digits_ltc(b!("__.45"), 10, b'_'), (b!("__"), b!(".45")));
1112         assert_eq!(consume_digits_ltc(b!("4_5"), 10, b'_'), (b!("4"), b!("_5")));
1113         assert_eq!(consume_digits_ltc(b!("4__5"), 10, b'_'), (b!("4"), b!("__5")));
1114         assert_eq!(consume_digits_ltc(b!("4_"), 10, b'_'), (b!("4_"), b!("")));
1115         assert_eq!(consume_digits_ltc(b!("4__"), 10, b'_'), (b!("4__"), b!("")));
1116         assert_eq!(consume_digits_ltc(b!("4_."), 10, b'_'), (b!("4_"), b!(".")));
1117         assert_eq!(consume_digits_ltc(b!("4__."), 10, b'_'), (b!("4__"), b!(".")));
1118         assert_eq!(consume_digits_ltc(b!("_45_5"), 10, b'_'), (b!("_45"), b!("_5")));
1119         assert_eq!(consume_digits_ltc(b!("__45__5"), 10, b'_'), (b!("__45"), b!("__5")));
1120         assert_eq!(consume_digits_ltc(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5")));
1121         assert_eq!(consume_digits_ltc(b!("__.45__5"), 10, b'_'), (b!("__"), b!(".45__5")));
1122         assert_eq!(consume_digits_ltc(b!("4_5_"), 10, b'_'), (b!("4"), b!("_5_")));
1123         assert_eq!(consume_digits_ltc(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__")));
1124         assert_eq!(consume_digits_ltc(b!("4_5_.5"), 10, b'_'), (b!("4"), b!("_5_.5")));
1125         assert_eq!(consume_digits_ltc(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5")));
1126         assert_eq!(consume_digits_ltc(b!("_45_"), 10, b'_'), (b!("_45_"), b!("")));
1127         assert_eq!(consume_digits_ltc(b!("__45__"), 10, b'_'), (b!("__45__"), b!("")));
1128         assert_eq!(consume_digits_ltc(b!("_45_.56"), 10, b'_'), (b!("_45_"), b!(".56")));
1129         assert_eq!(consume_digits_ltc(b!("__45__.56"), 10, b'_'), (b!("__45__"), b!(".56")));
1130         assert_eq!(consume_digits_ltc(b!("_4_5_"), 10, b'_'), (b!("_4"), b!("_5_")));
1131         assert_eq!(consume_digits_ltc(b!("__4__5__"), 10, b'_'), (b!("__4"), b!("__5__")));
1132         assert_eq!(consume_digits_ltc(b!("_4_5_.56"), 10, b'_'), (b!("_4"), b!("_5_.56")));
1133         assert_eq!(consume_digits_ltc(b!("__4__5__.56"), 10, b'_'), (b!("__4"), b!("__5__.56")));
1134     }
1135 
1136     #[cfg(feature = "format")]
1137     #[test]
consume_digits_ilt_test()1138     fn consume_digits_ilt_test() {
1139         assert_eq!(consume_digits_ilt(b!("123.45"), 10, b'_'), (b!("123"), b!(".45")));
1140         assert_eq!(consume_digits_ilt(b!("1e45"), 10, b'_'), (b!("1"), b!("e45")));
1141         assert_eq!(consume_digits_ilt(b!("1e"), 10, b'_'), (b!("1"), b!("e")));
1142         assert_eq!(consume_digits_ilt(b!("1"), 10, b'_'), (b!("1"), b!("")));
1143         assert_eq!(consume_digits_ilt(b!("_45"), 10, b'_'), (b!("_45"), b!("")));
1144         assert_eq!(consume_digits_ilt(b!("__45"), 10, b'_'), (b!(""), b!("__45")));
1145         assert_eq!(consume_digits_ilt(b!("4_5"), 10, b'_'), (b!("4_5"), b!("")));
1146         assert_eq!(consume_digits_ilt(b!("4__5"), 10, b'_'), (b!("4"), b!("__5")));
1147         assert_eq!(consume_digits_ilt(b!("_.45"), 10, b'_'), (b!("_"), b!(".45")));
1148         assert_eq!(consume_digits_ilt(b!("__.45"), 10, b'_'), (b!(""), b!("__.45")));
1149         assert_eq!(consume_digits_ilt(b!("4_"), 10, b'_'), (b!("4_"), b!("")));
1150         assert_eq!(consume_digits_ilt(b!("4__"), 10, b'_'), (b!("4"), b!("__")));
1151         assert_eq!(consume_digits_ilt(b!("4_."), 10, b'_'), (b!("4_"), b!(".")));
1152         assert_eq!(consume_digits_ilt(b!("4__."), 10, b'_'), (b!("4"), b!("__.")));
1153         assert_eq!(consume_digits_ilt(b!("_45_5"), 10, b'_'), (b!("_45_5"), b!("")));
1154         assert_eq!(consume_digits_ilt(b!("__45__5"), 10, b'_'), (b!(""), b!("__45__5")));
1155         assert_eq!(consume_digits_ilt(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5")));
1156         assert_eq!(consume_digits_ilt(b!("__.45__5"), 10, b'_'), (b!(""), b!("__.45__5")));
1157         assert_eq!(consume_digits_ilt(b!("4_5_"), 10, b'_'), (b!("4_5_"), b!("")));
1158         assert_eq!(consume_digits_ilt(b!("4__5__"), 10, b'_'), (b!("4"), b!("__5__")));
1159         assert_eq!(consume_digits_ilt(b!("4_5_.5"), 10, b'_'), (b!("4_5_"), b!(".5")));
1160         assert_eq!(consume_digits_ilt(b!("4__5__.5"), 10, b'_'), (b!("4"), b!("__5__.5")));
1161         assert_eq!(consume_digits_ilt(b!("_45_"), 10, b'_'), (b!("_45_"), b!("")));
1162         assert_eq!(consume_digits_ilt(b!("__45__"), 10, b'_'), (b!(""), b!("__45__")));
1163         assert_eq!(consume_digits_ilt(b!("_45_.56"), 10, b'_'), (b!("_45_"), b!(".56")));
1164         assert_eq!(consume_digits_ilt(b!("__45__.56"), 10, b'_'), (b!(""), b!("__45__.56")));
1165         assert_eq!(consume_digits_ilt(b!("_4_5_"), 10, b'_'), (b!("_4_5_"), b!("")));
1166         assert_eq!(consume_digits_ilt(b!("__4__5__"), 10, b'_'), (b!(""), b!("__4__5__")));
1167         assert_eq!(consume_digits_ilt(b!("_4_5_.56"), 10, b'_'), (b!("_4_5_"), b!(".56")));
1168         assert_eq!(consume_digits_ilt(b!("__4__5__.56"), 10, b'_'), (b!(""), b!("__4__5__.56")));
1169 
1170         assert_eq!(consume_digits_iltc(b!("123.45"), 10, b'_'), (b!("123"), b!(".45")));
1171         assert_eq!(consume_digits_iltc(b!("1e45"), 10, b'_'), (b!("1"), b!("e45")));
1172         assert_eq!(consume_digits_iltc(b!("1e"), 10, b'_'), (b!("1"), b!("e")));
1173         assert_eq!(consume_digits_iltc(b!("1"), 10, b'_'), (b!("1"), b!("")));
1174         assert_eq!(consume_digits_iltc(b!("_45"), 10, b'_'), (b!("_45"), b!("")));
1175         assert_eq!(consume_digits_iltc(b!("__45"), 10, b'_'), (b!("__45"), b!("")));
1176         assert_eq!(consume_digits_iltc(b!("_.45"), 10, b'_'), (b!("_"), b!(".45")));
1177         assert_eq!(consume_digits_iltc(b!("__.45"), 10, b'_'), (b!("__"), b!(".45")));
1178         assert_eq!(consume_digits_iltc(b!("4_5"), 10, b'_'), (b!("4_5"), b!("")));
1179         assert_eq!(consume_digits_iltc(b!("4__5"), 10, b'_'), (b!("4__5"), b!("")));
1180         assert_eq!(consume_digits_iltc(b!("4_"), 10, b'_'), (b!("4_"), b!("")));
1181         assert_eq!(consume_digits_iltc(b!("4__"), 10, b'_'), (b!("4__"), b!("")));
1182         assert_eq!(consume_digits_iltc(b!("4_."), 10, b'_'), (b!("4_"), b!(".")));
1183         assert_eq!(consume_digits_iltc(b!("4__."), 10, b'_'), (b!("4__"), b!(".")));
1184         assert_eq!(consume_digits_iltc(b!("_45_5"), 10, b'_'), (b!("_45_5"), b!("")));
1185         assert_eq!(consume_digits_iltc(b!("__45__5"), 10, b'_'), (b!("__45__5"), b!("")));
1186         assert_eq!(consume_digits_iltc(b!("_.45_5"), 10, b'_'), (b!("_"), b!(".45_5")));
1187         assert_eq!(consume_digits_iltc(b!("__.45__5"), 10, b'_'), (b!("__"), b!(".45__5")));
1188         assert_eq!(consume_digits_iltc(b!("4_5_"), 10, b'_'), (b!("4_5_"), b!("")));
1189         assert_eq!(consume_digits_iltc(b!("4__5__"), 10, b'_'), (b!("4__5__"), b!("")));
1190         assert_eq!(consume_digits_iltc(b!("4_5_.5"), 10, b'_'), (b!("4_5_"), b!(".5")));
1191         assert_eq!(consume_digits_iltc(b!("4__5__.5"), 10, b'_'), (b!("4__5__"), b!(".5")));
1192         assert_eq!(consume_digits_iltc(b!("_45_"), 10, b'_'), (b!("_45_"), b!("")));
1193         assert_eq!(consume_digits_iltc(b!("__45__"), 10, b'_'), (b!("__45__"), b!("")));
1194         assert_eq!(consume_digits_iltc(b!("_45_.56"), 10, b'_'), (b!("_45_"), b!(".56")));
1195         assert_eq!(consume_digits_iltc(b!("__45__.56"), 10, b'_'), (b!("__45__"), b!(".56")));
1196         assert_eq!(consume_digits_iltc(b!("_4_5_"), 10, b'_'), (b!("_4_5_"), b!("")));
1197         assert_eq!(consume_digits_iltc(b!("__4__5__"), 10, b'_'), (b!("__4__5__"), b!("")));
1198         assert_eq!(consume_digits_iltc(b!("_4_5_.56"), 10, b'_'), (b!("_4_5_"), b!(".56")));
1199         assert_eq!(consume_digits_iltc(b!("__4__5__.56"), 10, b'_'), (b!("__4__5__"), b!(".56")));
1200     }
1201 }
1202