use std::collections::HashSet;
use crate::diff::FileDiff;
pub(super) const AUTO_COLLAPSE_PATTERNS: &[&str] = &[
"Gemfile.lock",
"db/schema.rb",
"db/structure.sql",
"package-lock.json",
"yarn.lock",
"pnpm-lock.yaml",
"bun.lockb",
"Cargo.lock",
"poetry.lock",
"Pipfile.lock",
"pdm.lock",
"composer.lock",
"packages.lock.json",
"go.sum",
"mix.lock",
"Package.resolved",
"pubspec.lock",
];
pub(super) fn should_auto_collapse(path: &str) -> bool {
AUTO_COLLAPSE_PATTERNS
.iter()
.any(|pattern| path.ends_with(pattern))
}
pub(super) fn is_deleted_file(header_content: &str) -> bool {
header_content.ends_with("(deleted)")
}
pub(super) fn auto_collapse_files(
files: &[FileDiff],
collapsed_files: &mut HashSet<String>,
manually_toggled: &HashSet<String>,
) {
for file in files {
if let Some(first_line) = file.lines.first()
&& let Some(ref path) = first_line.file_path
{
if manually_toggled.contains(path) {
continue;
}
let is_pattern_match = should_auto_collapse(path);
let is_deleted = is_deleted_file(&first_line.content);
if is_pattern_match || is_deleted {
collapsed_files.insert(path.clone());
} else if collapsed_files.contains(path) {
collapsed_files.remove(path);
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_should_auto_collapse_patterns() {
assert!(should_auto_collapse("Cargo.lock"));
assert!(should_auto_collapse("path/to/Cargo.lock"));
assert!(should_auto_collapse("package-lock.json"));
assert!(should_auto_collapse("yarn.lock"));
assert!(should_auto_collapse("Gemfile.lock"));
assert!(should_auto_collapse("db/schema.rb"));
assert!(!should_auto_collapse("Cargo.toml"));
assert!(!should_auto_collapse("package.json"));
assert!(!should_auto_collapse("main.rs"));
assert!(!should_auto_collapse("lock.txt"));
}
#[test]
fn test_is_deleted_file() {
assert!(is_deleted_file("path/to/file.rs (deleted)"));
assert!(is_deleted_file("file.txt (deleted)"));
assert!(!is_deleted_file("path/to/file.rs"));
assert!(!is_deleted_file("deleted_file.rs"));
assert!(!is_deleted_file("(deleted) file.rs"));
}
}