#![cfg_attr(coverage_nightly, coverage(off))]
use std::path::Path;
pub(super) const DOT_UNWRAP: &str = concat!(".unwr", "ap()");
pub(super) const DOT_EXPECT_QUOTE: &str = concat!(".expe", "ct(\"");
pub(super) const UNWRAP_OR_ELSE_DISCARD: &str = concat!(".unwrap_or_el", "se(|_|");
pub(super) const MAP_ERR_DISCARD: &str = concat!(".map_er", "r(|_|");
pub(super) const EPRINTLN_DEBUG: &str = concat!("eprintln!(\"[DEB", "UG");
pub(super) const EPRINTLN_DBG: &str = concat!("eprintln!(\"[DB", "G");
pub(super) const EPRINTLN_TRACE: &str = concat!("eprintln!(\"[TRA", "CE");
pub(super) fn is_fn_start(trimmed: &str) -> bool {
trimmed.starts_with("pub fn ")
|| trimmed.starts_with("fn ")
|| trimmed.starts_with("pub async fn ")
|| trimmed.starts_with("async fn ")
}
pub(super) fn is_loop_start(trimmed: &str) -> bool {
trimmed.starts_with("for ")
|| trimmed.starts_with("while ")
|| trimmed == "loop {"
|| trimmed.starts_with("loop {")
}
pub(super) fn is_spawn_call(trimmed: &str) -> bool {
trimmed.contains("thread::spawn")
|| trimmed.contains("tokio::spawn")
|| trimmed.contains("rayon::spawn")
|| trimmed.contains("spawn_blocking")
}
pub(super) fn is_macro_in_string_literal(trimmed: &str, macros: &[&str]) -> bool {
if !trimmed.contains('"') {
return false;
}
let before_string = trimmed.split('"').next().unwrap_or("");
!macros.iter().any(|m| before_string.contains(m))
}
pub(super) fn walkdir_files_with_ext(
dir: &Path,
ext: &str,
) -> Result<Vec<std::path::PathBuf>, std::io::Error> {
let mut files = Vec::new();
for entry in std::fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
files.extend(walkdir_files_with_ext(&path, ext)?);
} else if path.extension().map(|e| e == ext).unwrap_or(false) {
files.push(path);
}
}
Ok(files)
}
pub(super) fn is_test_fn_definition(trimmed: &str, line_idx: usize, lines: &[&str]) -> bool {
let has_test_attr = (1..=3).any(|back| {
line_idx >= back && {
let prev = lines[line_idx - back].trim();
prev == "#[test]" || prev == "#[tokio::test]" || prev.starts_with("#[cfg(test")
}
});
let fn_name_lower = trimmed.to_lowercase();
has_test_attr
|| fn_name_lower.contains("test_")
|| fn_name_lower.contains("_test")
|| fn_name_lower.contains("roundtrip")
}
pub(super) const LOSSY_TRANSFORM_PAIRS: &[(&str, &str, &[&str])] = &[
("quantize", "dequantize", &["quant", "qlora", "lora"]),
(
"encode",
"decode",
&["codec", "encoding", "decoder", "encoder"],
),
(
"compress",
"decompress",
&["compress", "zlib", "gzip", "lz4", "zstd"],
),
("serialize", "deserialize", &["serde", "serial", "marshal"]),
("pack", "unpack", &["pack", "msgpack"]),
("to_bytes", "from_bytes", &["bytes", "binary"]),
("to_f16", "to_f32", &[]),
("to_bf16", "to_f32", &[]),
];
pub(super) fn find_lossy_pair<'a>(fn_content: &str, file_path: &str) -> Option<(&'a str, &'a str)> {
let filtered: String = fn_content
.lines()
.filter(|l| {
let t = l.trim();
!t.starts_with("#[derive(") && !t.starts_with("//")
})
.collect::<Vec<_>>()
.join("\n")
.to_lowercase();
let path_lower = file_path.to_lowercase();
LOSSY_TRANSFORM_PAIRS.iter().find_map(|(fwd, rev, stems)| {
if stems.iter().any(|s| path_lower.contains(s)) {
return None;
}
if !filtered.contains(*rev) {
return None;
}
let without_rev = filtered.replace(rev, "");
if without_rev.contains(*fwd) {
Some((*fwd, *rev))
} else {
None
}
})
}
pub(super) const BINARY_READ_PATTERNS: &[&str] = &[
"read_exact(",
"from_le_bytes(",
"from_be_bytes(",
"read_u32::",
"read_u64::",
"read_i32::",
"read_i64::",
];
pub(super) const MAGIC_VALIDATION_PATTERNS: &[&str] = &[
"magic",
"MAGIC",
"signature",
"SIGNATURE",
"header_magic",
"file_type",
"format_version",
"FILE_MAGIC",
];
pub(super) const IO_CONTEXT_PATTERNS: &[&str] = &[
"File::",
"BufReader",
"BufRead",
"Cursor::",
"stdin",
"from_reader(",
".read(",
".read_to_end(",
"open(",
"Read>",
"impl Read",
];
pub(super) fn classify_cb521_line(trimmed: &str) -> (bool, bool, bool) {
let binary = BINARY_READ_PATTERNS.iter().any(|p| trimmed.contains(p));
let magic = MAGIC_VALIDATION_PATTERNS
.iter()
.any(|p| trimmed.contains(p));
let io = IO_CONTEXT_PATTERNS.iter().any(|p| trimmed.contains(p));
(binary, magic, io)
}
pub(super) const EXPENSIVE_INIT_PATTERNS: &[&str] = &[
"::new(",
"::open(",
"::connect(",
"::create(",
"::load(",
"::init(",
"::build(",
"::from_file(",
"::from_path(",
"::read_to_string(",
"File::open(",
];
pub(super) fn is_cast_allowed(lines: &[&str], i: usize) -> bool {
let trimmed = lines[i].trim();
if trimmed.contains("allow(clippy::cast") {
return true;
}
for back in 1..=5 {
if i < back {
break;
}
let prev = lines[i - back].trim();
if prev.contains("allow(clippy::cast") || prev.starts_with("// SAFETY:") {
return true;
}
if !prev.starts_with("#[") && !prev.starts_with("//") && !prev.is_empty() {
break;
}
}
false
}