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