use std::path::Path;
pub fn path_matches_pattern(path: &Path, pattern: &str) -> bool {
let requires_directory = pattern.ends_with('/');
let pattern_components: Vec<&str> = pattern.split('/').filter(|c| !c.is_empty()).collect();
if pattern_components.is_empty() {
return false;
}
let components: Vec<String> = path
.components()
.map(|c| c.as_os_str().to_string_lossy().into_owned())
.collect();
let needed = pattern_components.len();
if components.len() < needed {
return false;
}
for start in 0..=(components.len() - needed) {
let matches = components[start..start + needed]
.iter()
.zip(&pattern_components)
.all(|(component, pattern_component)| component == pattern_component);
if matches && (!requires_directory || start + needed < components.len()) {
return true;
}
}
false
}
pub fn is_example_path(path: &Path) -> bool {
path_matches_pattern(path, "examples/")
}
pub fn is_bench_path(path: &Path) -> bool {
path_matches_pattern(path, "benches/")
}
pub fn is_test_path(path: &Path) -> bool {
path_matches_pattern(path, "tests/")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_example_paths() {
assert!(is_example_path(Path::new("examples/main.rs")));
assert!(is_example_path(Path::new("crate/examples/demo.rs")));
assert!(!is_example_path(Path::new("src/examples.rs")));
}
#[test]
fn test_bench_paths() {
assert!(is_bench_path(Path::new("benches/perf.rs")));
assert!(!is_bench_path(Path::new("src/benches.rs")));
}
#[test]
fn test_test_paths() {
assert!(is_test_path(Path::new("tests/integration.rs")));
assert!(!is_test_path(Path::new("src/tests.rs")));
}
#[test]
fn test_component_boundaries() {
assert!(!is_test_path(Path::new("src/attests/mod.rs")));
assert!(!is_test_path(Path::new("src/contests/x.rs")));
assert!(!is_bench_path(Path::new("src/benches_util/x.rs")));
assert!(is_test_path(Path::new("crate/tests/deep/it.rs")));
}
#[test]
fn test_pattern_matching_rules() {
assert!(path_matches_pattern(Path::new("src/gen/out.rs"), "src/gen"));
assert!(!path_matches_pattern(
Path::new("src/generic.rs"),
"src/gen"
));
assert!(path_matches_pattern(
Path::new("src/gen/out.rs"),
"src/gen/"
));
assert!(!path_matches_pattern(Path::new("a/tests"), "tests/"));
assert!(!path_matches_pattern(Path::new("src/lib.rs"), ""));
}
}