Skip to content

Commit b62543f

Browse files
author
Michael Wright
committed
literal representation restructure 7
Replace `do_lint` with `get_group_size`. Return `None` if there are no groups.
1 parent abf62d8 commit b62543f

File tree

1 file changed

+28
-39
lines changed

1 file changed

+28
-39
lines changed

clippy_lints/src/literal_representation.rs

Lines changed: 28 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -397,10 +397,9 @@ impl LiteralDigitGrouping {
397397

398398
let (integer, fraction, _) = digit_info.split_digit_parts();
399399

400-
let integral_group_size = Self::do_lint(integer, in_macro)?;
400+
let integral_group_size = Self::get_group_size(integer.split('_'), in_macro)?;
401401
if let Some(fraction) = fraction {
402-
let fractional_part = fraction.chars().rev().collect::<String>();
403-
let fractional_group_size = Self::do_lint(&fractional_part, in_macro)?;
402+
let fractional_group_size = Self::get_group_size(fraction.rsplit('_'), in_macro)?;
404403

405404
let consistent = Self::parts_consistent(integral_group_size,
406405
fractional_group_size,
@@ -425,53 +424,43 @@ impl LiteralDigitGrouping {
425424
/// parts, and the length
426425
/// of both parts, determine if the digits have been grouped consistently.
427426
#[must_use]
428-
fn parts_consistent(int_group_size: usize, frac_group_size: usize, int_size: usize, frac_size: usize) -> bool {
427+
fn parts_consistent(
428+
int_group_size: Option<usize>,
429+
frac_group_size: Option<usize>,
430+
int_size: usize,
431+
frac_size: usize,
432+
) -> bool {
429433
match (int_group_size, frac_group_size) {
430434
// No groups on either side of decimal point - trivially consistent.
431-
(0, 0) => true,
435+
(None, None) => true,
432436
// Integral part has grouped digits, fractional part does not.
433-
(_, 0) => frac_size <= int_group_size,
437+
(Some(int_group_size), None) => frac_size <= int_group_size,
434438
// Fractional part has grouped digits, integral part does not.
435-
(0, _) => int_size <= frac_group_size,
439+
(None, Some(frac_group_size)) => int_size <= frac_group_size,
436440
// Both parts have grouped digits. Groups should be the same size.
437-
(_, _) => int_group_size == frac_group_size,
441+
(Some(int_group_size), Some(frac_group_size)) => int_group_size == frac_group_size,
438442
}
439443
}
440444

441-
/// Performs lint on `digits` (no decimal point) and returns the group
442-
/// size on success or `WarningType` when emitting a warning.
443-
fn do_lint(digits: &str, in_macro: bool) -> Result<usize, WarningType> {
444-
// Grab underscore indices with respect to the units digit.
445-
let underscore_positions: Vec<usize> = digits
446-
.chars()
447-
.rev()
448-
.enumerate()
449-
.filter_map(|(idx, digit)| if digit == '_' { Some(idx) } else { None })
450-
.collect();
451-
452-
if underscore_positions.is_empty() {
453-
// Check if literal needs underscores.
454-
if !in_macro && digits.len() > 5 {
455-
Err(WarningType::UnreadableLiteral)
445+
/// Returns the size of the digit groups (or None if ungrouped) if successful,
446+
/// otherwise returns a `WarningType` for linting.
447+
fn get_group_size<'a>(groups: impl Iterator<Item = &'a str>, in_macro: bool) -> Result<Option<usize>, WarningType> {
448+
let mut groups = groups.map(str::len);
449+
450+
let first = groups.next().expect("At least one group");
451+
452+
if let Some(second) = groups.next() {
453+
if !groups.all(|x| x == second) || first > second {
454+
Err(WarningType::InconsistentDigitGrouping)
455+
} else if second > 4 {
456+
Err(WarningType::LargeDigitGroups)
456457
} else {
457-
Ok(0)
458+
Ok(Some(second))
458459
}
460+
} else if first > 5 && !in_macro {
461+
Err(WarningType::UnreadableLiteral)
459462
} else {
460-
// Check consistency and the sizes of the groups.
461-
let group_size = underscore_positions[0];
462-
let consistent = underscore_positions
463-
.windows(2)
464-
.all(|ps| ps[1] - ps[0] == group_size + 1)
465-
// number of digits to the left of the last group cannot be bigger than group size.
466-
&& (digits.len() - underscore_positions.last()
467-
.expect("there's at least one element") <= group_size + 1);
468-
469-
if !consistent {
470-
return Err(WarningType::InconsistentDigitGrouping);
471-
} else if group_size > 4 {
472-
return Err(WarningType::LargeDigitGroups);
473-
}
474-
Ok(group_size)
463+
Ok(None)
475464
}
476465
}
477466
}

0 commit comments

Comments
 (0)