use std::path::Path;
use super::defaults::{CollapsePattern, PurposePattern};
pub fn should_collapse<'a>(dir_name: &str, dir_path: &Path, patterns: &'a [CollapsePattern]) -> Option<&'a CollapsePattern> {
for pattern in patterns {
if dir_name == pattern.name {
if let Some(indicator) = pattern.indicator {
let indicator_path = dir_path.join(indicator);
if indicator_path.exists() {
return Some(pattern);
}
} else {
return Some(pattern);
}
}
}
None
}
pub fn should_ignore(filename: &str, patterns: &[&str]) -> bool {
for pattern in patterns {
if matches_glob(filename, pattern) {
return true;
}
}
false
}
pub fn detect_purpose(filename: &str, patterns: &[PurposePattern]) -> Option<&'static str> {
for pattern in patterns {
if matches_glob(filename, pattern.pattern) {
return Some(pattern.purpose);
}
}
None
}
fn matches_glob(text: &str, pattern: &str) -> bool {
if pattern == text {
return true;
}
if pattern.starts_with('*') && pattern.ends_with('*') {
let middle = &pattern[1..pattern.len() - 1];
return text.contains(middle);
}
if pattern.starts_with('*') {
let suffix = &pattern[1..];
return text.ends_with(suffix);
}
if pattern.ends_with('*') {
let prefix = &pattern[..pattern.len() - 1];
return text.starts_with(prefix);
}
false
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_matches_glob() {
assert!(matches_glob("test_foo.py", "test_*.py"));
assert!(matches_glob("foo_test.py", "*_test.py"));
assert!(matches_glob("main.py", "main.py"));
assert!(matches_glob("foo.spec.ts", "*.spec.ts"));
assert!(!matches_glob("main.rs", "main.py"));
assert!(!matches_glob("test_foo.py", "*_test.py"));
}
#[test]
fn test_should_ignore() {
let patterns = vec![".DS_Store", "*.pyc", "*~"];
assert!(should_ignore(".DS_Store", &patterns));
assert!(should_ignore("foo.pyc", &patterns));
assert!(should_ignore("backup~", &patterns));
assert!(!should_ignore("main.py", &patterns));
}
}