use std::path::{Component, Path};
#[cfg(test)]
mod tests {
use super::*;
use std::path::Path;
#[test]
fn test_addr_matches_filter_exact_match() {
let prefix = Path::new("some/prefix");
let addr = Path::new("aws/iam/user/jon.ron");
let filter = Path::new("some/prefix/aws/iam/user/jon.ron");
assert_eq!(addr_matches_filter(prefix, addr, filter), true);
}
#[test]
fn test_addr_matches_filter_prefix_match() {
let prefix = Path::new("some/prefix");
let addr = Path::new("aws/iam/user/jon.ron");
let filter = Path::new("some/prefix");
assert_eq!(addr_matches_filter(prefix, addr, filter), true);
}
#[test]
fn test_addr_matches_filter_parent_prefix_match() {
let prefix = Path::new("some/prefix");
let addr = Path::new("aws/iam/user/jon.ron");
let filter = Path::new("./some/*");
assert_eq!(addr_matches_filter(prefix, addr, filter), true);
}
#[test]
fn test_addr_matches_filter_no_match() {
let prefix = Path::new("another/prefix");
let addr = Path::new("aws/iam/user/jon.ron");
let filter = Path::new("some/./");
assert_eq!(addr_matches_filter(prefix, addr, filter), false);
}
#[test]
fn test_addr_matches_filter_wildcard_match() {
let prefix = Path::new("some/prefix");
let addr = Path::new("aws/iam/user/jon.ron");
let filter = Path::new("*/*/aws");
assert_eq!(addr_matches_filter(prefix, addr, filter), true);
}
#[test]
fn test_addr_matches_filter_wildcard_mismatch() {
let prefix = Path::new("some/prefix");
let addr = Path::new("aws/iam/user/jon.ron");
let filter = Path::new("*/iam/user/other");
assert_eq!(addr_matches_filter(prefix, addr, filter), false);
}
#[test]
fn test_addr_matches_filter_wildcard_at_start() {
let prefix = Path::new("some/prefix");
let addr = Path::new("aws/iam/user/jon.ron");
let filter = Path::new("*/*/aws/iam/user/jon.ron");
assert_eq!(addr_matches_filter(prefix, addr, filter), true);
}
}
pub fn addr_matches_filter(prefix: &Path, addr: &Path, filter: &Path) -> bool {
let full_path = prefix.join(addr);
let full_path_components: Vec<Component<'_>> = full_path
.components()
.filter(|c| *c != Component::CurDir)
.collect();
let filter_components: Vec<Component<'_>> = filter
.components()
.filter(|c| *c != Component::CurDir)
.collect();
if filter_components.len() > full_path_components.len() {
return false;
}
for (full_path_component, filter_component) in
full_path_components.iter().zip(filter_components)
{
match (full_path_component, filter_component) {
(Component::Normal(full), Component::Normal(filter)) => {
if *full == filter {
continue;
}
if filter.to_str() == Some("*") {
continue;
}
return false;
}
_ => return false,
}
}
true
}