1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

refactor wc.rs to remove clippy's cognitive complexity lint (#5897)

* refactor wc.rs to remove clippy's cognitive complexity lint

* fix for tracking line length and number of words correctly if chunking occurs within them

* removing more of the cognitive complexity from the Err variant in the match block

* running cargo clippy once

* wc: add empty line to separate functions

---------

Co-authored-by: Daniel Hofstetter <daniel.hofstetter@42dh.com>
This commit is contained in:
Harsh Ranjan 2024-01-29 15:11:11 +05:30 committed by GitHub
parent 08f07f9bfd
commit 1528b35113
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -565,7 +565,65 @@ fn word_count_from_reader<T: WordCountable>(
}
}
#[allow(clippy::cognitive_complexity)]
fn process_chunk<
const SHOW_CHARS: bool,
const SHOW_LINES: bool,
const SHOW_MAX_LINE_LENGTH: bool,
const SHOW_WORDS: bool,
>(
total: &mut WordCount,
text: &str,
current_len: &mut usize,
in_word: &mut bool,
) {
for ch in text.chars() {
if SHOW_WORDS {
if ch.is_whitespace() {
*in_word = false;
} else if ch.is_ascii_control() {
// These count as characters but do not affect the word state
} else if !(*in_word) {
*in_word = true;
total.words += 1;
}
}
if SHOW_MAX_LINE_LENGTH {
match ch {
'\n' | '\r' | '\x0c' => {
total.max_line_length = max(*current_len, total.max_line_length);
*current_len = 0;
}
'\t' => {
*current_len -= *current_len % 8;
*current_len += 8;
}
_ => {
*current_len += ch.width().unwrap_or(0);
}
}
}
if SHOW_LINES && ch == '\n' {
total.lines += 1;
}
if SHOW_CHARS {
total.chars += 1;
}
}
total.bytes += text.len();
total.max_line_length = max(*current_len, total.max_line_length);
}
fn handle_error(error: BufReadDecoderError<'_>, total: &mut WordCount) -> Option<io::Error> {
match error {
BufReadDecoderError::InvalidByteSequence(bytes) => {
total.bytes += bytes.len();
}
BufReadDecoderError::Io(e) => return Some(e),
}
None
}
fn word_count_from_reader_specialized<
T: WordCountable,
const SHOW_CHARS: bool,
@ -579,58 +637,24 @@ fn word_count_from_reader_specialized<
let mut reader = BufReadDecoder::new(reader.buffered());
let mut in_word = false;
let mut current_len = 0;
while let Some(chunk) = reader.next_strict() {
match chunk {
Ok(text) => {
for ch in text.chars() {
if SHOW_WORDS {
if ch.is_whitespace() {
in_word = false;
} else if ch.is_ascii_control() {
// These count as characters but do not affect the word state
} else if !in_word {
in_word = true;
total.words += 1;
}
}
if SHOW_MAX_LINE_LENGTH {
match ch {
'\n' | '\r' | '\x0c' => {
total.max_line_length = max(current_len, total.max_line_length);
current_len = 0;
}
'\t' => {
current_len -= current_len % 8;
current_len += 8;
}
_ => {
current_len += ch.width().unwrap_or(0);
}
}
}
if SHOW_LINES && ch == '\n' {
total.lines += 1;
}
if SHOW_CHARS {
total.chars += 1;
}
process_chunk::<SHOW_CHARS, SHOW_LINES, SHOW_MAX_LINE_LENGTH, SHOW_WORDS>(
&mut total,
text,
&mut current_len,
&mut in_word,
);
}
Err(e) => {
if let Some(e) = handle_error(e, &mut total) {
return (total, Some(e));
}
total.bytes += text.len();
}
Err(BufReadDecoderError::InvalidByteSequence(bytes)) => {
// GNU wc treats invalid data as neither word nor char nor whitespace,
// so no other counters are affected
total.bytes += bytes.len();
}
Err(BufReadDecoderError::Io(e)) => {
return (total, Some(e));
}
}
}
total.max_line_length = max(current_len, total.max_line_length);
(total, None)
}