emptiness tested through len() instead of is_empty()
ID |
rust.maintainability.container_size_empty |
Severity |
info |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Idiom |
Language |
Rust |
Description
Reports a comparison of len() against zero or one that only asks whether a collection or string is empty.
Rationale
len() == 0, len() > 0 and len() < 1 all mean "is it empty", but each states it differently, so a reader has to decode the comparison and check for an off-by-one before moving on. is_empty() says it once, is what the standard library documents, and is the form every container implements directly - for a type whose length is not stored, such as a linked list or a char-counting iterator adapter, computing the length to compare it with zero also walks the whole structure.
The following code illustrates the pattern detected by this rule:
fn summarize(names: &Vec<String>, tags: &[u32], label: &String) -> &'static str {
// FLAGGED: emptiness tested through len() instead of is_empty()
if names.len() == 0 {
return "no names";
}
// FLAGGED: emptiness tested through len() instead of is_empty()
if 0 == tags.len() {
return "no tags";
}
// FLAGGED: emptiness tested through len() instead of is_empty()
if label.len() != 0 {
return "labelled";
}
// FLAGGED: emptiness tested through len() instead of is_empty()
if names.len() > 0 {
return "named";
}
// FLAGGED: emptiness tested through len() instead of is_empty()
if tags.len() < 1 {
return "no tags";
}
"unknown"
}