mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-20 03:22:18 +00:00
194 lines
9.5 KiB
Rust
194 lines
9.5 KiB
Rust
#[allow(dead_code)]
|
|
pub fn is_simple_match<P, N>(pattern: P, name: N) -> bool
|
|
where
|
|
P: AsRef<str>,
|
|
N: AsRef<str>,
|
|
{
|
|
inner_match(pattern, name, true)
|
|
}
|
|
|
|
pub fn is_match<P, N>(pattern: P, name: N) -> bool
|
|
where
|
|
P: AsRef<str>,
|
|
N: AsRef<str>,
|
|
{
|
|
inner_match(pattern, name, false)
|
|
}
|
|
|
|
#[allow(dead_code)]
|
|
pub fn is_match_as_pattern_prefix<P, N>(pattern: P, text: N) -> bool
|
|
where
|
|
P: AsRef<str>,
|
|
N: AsRef<str>,
|
|
{
|
|
let (mut p, mut t) = (pattern.as_ref().as_bytes().iter(), text.as_ref().as_bytes().iter());
|
|
|
|
while let (Some(&x), Some(&y)) = (p.next(), t.next()) {
|
|
if x == b'*' {
|
|
return true;
|
|
}
|
|
|
|
if x == b'?' {
|
|
continue;
|
|
}
|
|
|
|
if x != y {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
text.as_ref().len() <= pattern.as_ref().len()
|
|
}
|
|
|
|
#[inline]
|
|
fn inner_match(pattern: impl AsRef<str>, name: impl AsRef<str>, simple: bool) -> bool {
|
|
let (pattern, name) = (pattern.as_ref(), name.as_ref());
|
|
|
|
if pattern.is_empty() {
|
|
return pattern == name;
|
|
}
|
|
|
|
if pattern == "*" {
|
|
return true;
|
|
}
|
|
|
|
deep_match(pattern.as_bytes(), name.as_bytes(), simple)
|
|
}
|
|
|
|
fn deep_match(mut pattern: &[u8], mut name: &[u8], simple: bool) -> bool {
|
|
while !pattern.is_empty() {
|
|
match pattern[0] {
|
|
b'?' => {
|
|
if name.is_empty() {
|
|
return simple;
|
|
}
|
|
}
|
|
|
|
b'*' => {
|
|
return pattern.len() == 1
|
|
|| deep_match(&pattern[1..], name, simple)
|
|
|| (!name.is_empty() && deep_match(pattern, &name[1..], simple));
|
|
}
|
|
|
|
_ => {
|
|
if name.is_empty() || name[0] != pattern[0] {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
name = &name[1..];
|
|
pattern = &pattern[1..];
|
|
}
|
|
|
|
name.is_empty() && pattern.is_empty()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::{is_match, is_match_as_pattern_prefix, is_simple_match};
|
|
|
|
#[test_case::test_case("*", "s3:GetObject" => true ; "1")]
|
|
#[test_case::test_case("", "s3:GetObject" => false ; "2")]
|
|
#[test_case::test_case("", "" => true; "3")]
|
|
#[test_case::test_case("s3:*", "s3:ListMultipartUploadParts" => true; "4")]
|
|
#[test_case::test_case("s3:ListBucketMultipartUploads", "s3:ListBucket" => false; "5")]
|
|
#[test_case::test_case("s3:ListBucket", "s3:ListBucket" => true; "6")]
|
|
#[test_case::test_case("s3:ListBucketMultipartUploads", "s3:ListBucketMultipartUploads" => true; "7")]
|
|
#[test_case::test_case("my-bucket/oo*", "my-bucket/oo" => true; "8")]
|
|
#[test_case::test_case("my-bucket/In*", "my-bucket/India/Karnataka/" => true; "9")]
|
|
#[test_case::test_case("my-bucket/In*", "my-bucket/Karnataka/India/" => false; "10")]
|
|
#[test_case::test_case("my-bucket/In*/Ka*/Ban", "my-bucket/India/Karnataka/Ban" => true; "11")]
|
|
#[test_case::test_case("my-bucket/In*/Ka*/Ban", "my-bucket/India/Karnataka/Ban/Ban/Ban/Ban/Ban" => true; "12")]
|
|
#[test_case::test_case("my-bucket/In*/Ka*/Ban", "my-bucket/India/Karnataka/Area1/Area2/Area3/Ban" => true; "13")]
|
|
#[test_case::test_case( "my-bucket/In*/Ka*/Ba", "my-bucket/India/State1/State2/Karnataka/Area1/Area2/Area3/Ban" => ignore["will fail"] true; "14")]
|
|
#[test_case::test_case("my-bucket/In*/Ka*/Ban", "my-bucket/India/Karnataka/Bangalore" => false; "15")]
|
|
#[test_case::test_case("my-bucket/In*/Ka*/Ban*", "my-bucket/India/Karnataka/Bangalore" => true; "16")]
|
|
#[test_case::test_case("my-bucket/*", "my-bucket/India" => true; "17")]
|
|
#[test_case::test_case("my-bucket/oo*", "my-bucket/odo" => false; "18")]
|
|
#[test_case::test_case("my-bucket?/abc*", "mybucket/abc" => false; "19")]
|
|
#[test_case::test_case("my-bucket?/abc*", "my-bucket1/abc" => true; "20")]
|
|
#[test_case::test_case("my-?-bucket/abc*", "my--bucket/abc" => false; "21")]
|
|
#[test_case::test_case("my-?-bucket/abc*", "my-1-bucket/abc" => true; "22")]
|
|
#[test_case::test_case("my-?-bucket/abc*", "my-k-bucket/abc" => true; "23")]
|
|
#[test_case::test_case("my??bucket/abc*", "mybucket/abc" => false; "24")]
|
|
#[test_case::test_case("my??bucket/abc*", "my4abucket/abc" => true; "25")]
|
|
#[test_case::test_case("my-bucket?abc*", "my-bucket/abc" => true; "26")]
|
|
#[test_case::test_case("my-bucket/abc?efg", "my-bucket/abcdefg" => true; "27")]
|
|
#[test_case::test_case("my-bucket/abc?efg", "my-bucket/abc/efg" => true; "28")]
|
|
#[test_case::test_case("my-bucket/abc????", "my-bucket/abcde" => false; "29")]
|
|
#[test_case::test_case("my-bucket/abc????", "my-bucket/abcdefg" => true; "30")]
|
|
#[test_case::test_case("my-bucket/abc?", "my-bucket/abc" => false; "31")]
|
|
#[test_case::test_case("my-bucket/abc?", "my-bucket/abcd" => true; "32")]
|
|
#[test_case::test_case("my-bucket/abc?", "my-bucket/abcde" => false; "33")]
|
|
#[test_case::test_case("my-bucket/mnop*?", "my-bucket/mnop" => false; "34")]
|
|
#[test_case::test_case("my-bucket/mnop*?", "my-bucket/mnopqrst/mnopqr" => true; "35")]
|
|
#[test_case::test_case("my-bucket/mnop*?", "my-bucket/mnopqrst/mnopqrs" => true; "36")]
|
|
#[test_case::test_case("my-bucket/mnop*?", "my-bucket/mnop" => false; "37")]
|
|
#[test_case::test_case("my-bucket/mnop*?", "my-bucket/mnopq" => true; "38")]
|
|
#[test_case::test_case("my-bucket/mnop*?", "my-bucket/mnopqr" => true; "39")]
|
|
#[test_case::test_case("my-bucket/mnop*?and", "my-bucket/mnopqand" => true; "40")]
|
|
#[test_case::test_case("my-bucket/mnop*?and", "my-bucket/mnopand" => false; "41")]
|
|
#[test_case::test_case("my-bucket/mnop*?and", "my-bucket/mnopqand" => true; "42")]
|
|
#[test_case::test_case("my-bucket/mnop*?", "my-bucket/mn" => false; "43")]
|
|
#[test_case::test_case("my-bucket/mnop*?", "my-bucket/mnopqrst/mnopqrs" => true; "44")]
|
|
#[test_case::test_case("my-bucket/mnop*??", "my-bucket/mnopqrst" => true; "45")]
|
|
#[test_case::test_case("my-bucket/mnop*qrst", "my-bucket/mnopabcdegqrst" => true; "46")]
|
|
#[test_case::test_case("my-bucket/mnop*?and", "my-bucket/mnopqand" => true; "47")]
|
|
#[test_case::test_case("my-bucket/mnop*?and", "my-bucket/mnopand" => false; "48")]
|
|
#[test_case::test_case("my-bucket/mnop*?and?", "my-bucket/mnopqanda" => true; "49")]
|
|
#[test_case::test_case("my-bucket/mnop*?and", "my-bucket/mnopqanda" => false; "50")]
|
|
#[test_case::test_case("my-?-bucket/abc*", "my-bucket/mnopqanda" => false; "51")]
|
|
#[test_case::test_case("a?", "a" => false; "52")]
|
|
#[test_case::test_case("*", "mybucket/myobject" => true; "53")]
|
|
fn test_is_match(pattern: &str, text: &str) -> bool {
|
|
is_match(pattern, text)
|
|
}
|
|
|
|
#[test_case::test_case("*", "s3:GetObject" => true ; "1")]
|
|
#[test_case::test_case("", "s3:GetObject" => false ; "2")]
|
|
#[test_case::test_case("", "" => true ; "3")]
|
|
#[test_case::test_case("s3:*", "s3:ListMultipartUploadParts" => true ; "4")]
|
|
#[test_case::test_case("s3:ListBucketMultipartUploads", "s3:ListBucket" => false ; "5")]
|
|
#[test_case::test_case("s3:ListBucket", "s3:ListBucket" => true ; "6")]
|
|
#[test_case::test_case("s3:ListBucketMultipartUploads", "s3:ListBucketMultipartUploads" => true ; "7")]
|
|
#[test_case::test_case("my-bucket/oo*", "my-bucket/oo" => true ; "8")]
|
|
#[test_case::test_case("my-bucket/In*", "my-bucket/India/Karnataka/" => true ; "9")]
|
|
#[test_case::test_case("my-bucket/In*", "my-bucket/Karnataka/India/" => false ; "10")]
|
|
#[test_case::test_case("my-bucket/In*/Ka*/Ban", "my-bucket/India/Karnataka/Ban" => true ; "11")]
|
|
#[test_case::test_case("my-bucket/In*/Ka*/Ban", "my-bucket/India/Karnataka/Ban/Ban/Ban/Ban/Ban" => true ; "12")]
|
|
#[test_case::test_case("my-bucket/In*/Ka*/Ban", "my-bucket/India/Karnataka/Area1/Area2/Area3/Ban" => true ; "13")]
|
|
#[test_case::test_case("my-bucket/In*/Ka*/Ban", "my-bucket/India/State1/State2/Karnataka/Area1/Area2/Area3/Ban" => true ; "14")]
|
|
#[test_case::test_case("my-bucket/In*/Ka*/Ban", "my-bucket/India/Karnataka/Bangalore" => false ; "15")]
|
|
#[test_case::test_case("my-bucket/In*/Ka*/Ban*", "my-bucket/India/Karnataka/Bangalore" => true ; "16")]
|
|
#[test_case::test_case("my-bucket/*", "my-bucket/India" => true ; "17")]
|
|
#[test_case::test_case("my-bucket/oo*", "my-bucket/odo" => false ; "18")]
|
|
#[test_case::test_case("my-bucket/oo?*", "my-bucket/oo???" => true ; "19")]
|
|
#[test_case::test_case("my-bucket/oo??*", "my-bucket/odo" => false ; "20")]
|
|
#[test_case::test_case("?h?*", "?h?hello" => true ; "21")]
|
|
#[test_case::test_case("a?", "a" => true ; "22")]
|
|
fn test_is_simple_match(pattern: &str, text: &str) -> bool {
|
|
is_simple_match(pattern, text)
|
|
}
|
|
|
|
#[test_case::test_case("", "" => true ; "1")]
|
|
#[test_case::test_case("a", "" => true ; "2")]
|
|
#[test_case::test_case("a", "b" => false ; "3")]
|
|
#[test_case::test_case("abc", "ab" => true ; "4")]
|
|
#[test_case::test_case("ab*", "ab" => true ; "5")]
|
|
#[test_case::test_case("abc*", "ab" => true ; "6")]
|
|
#[test_case::test_case("abc?", "ab" => true ; "7")]
|
|
#[test_case::test_case("abc*", "abd" => false ; "8")]
|
|
#[test_case::test_case("abc*c", "abcd" => true ; "9")]
|
|
#[test_case::test_case("ab*??d", "abxxc" => true ; "10")]
|
|
#[test_case::test_case("ab*??", "abxc" => true ; "11")]
|
|
#[test_case::test_case("ab??", "abxc" => true ; "12")]
|
|
#[test_case::test_case("ab??", "abx" => true ; "13")]
|
|
#[test_case::test_case("ab??d", "abcxd" => true ; "14")]
|
|
#[test_case::test_case("ab??d", "abcxdd" => false ; "15")]
|
|
#[test_case::test_case("", "b" => false ; "16")]
|
|
fn test_is_match_as_pattern_prefix(pattern: &str, text: &str) -> bool {
|
|
is_match_as_pattern_prefix(pattern, text)
|
|
}
|
|
}
|