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:
parent
08f07f9bfd
commit
1528b35113
1 changed files with 69 additions and 45 deletions
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue