mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-18 10:43:15 +00:00
5826396cd0
This commit introduces a significant reorganization of the project structure to improve maintainability and clarity. Key changes include: - Adjusted the directory layout for a more logical module organization. - Removed unused crate dependencies, reducing the overall project size and potentially speeding up build times. - Updated import paths and configuration files to reflect the structural changes.
208 lines
10 KiB
Rust
208 lines
10 KiB
Rust
// Copyright 2024 RustFS Team
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#[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)
|
|
}
|
|
}
|