mirror of
https://git.proxmox.com/git/pathpatterns
synced 2025-06-19 20:56:26 +00:00
Relax MatchList to support slices of references
It must not consume `self`. Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
909586e6ad
commit
92591b0073
@ -325,6 +325,24 @@ impl MatchListEntry for &'_ MatchEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MatchListEntry for &'_ &'_ MatchEntry {
|
||||||
|
fn entry_matches(&self, path: &[u8], file_mode: Option<u32>) -> Option<MatchType> {
|
||||||
|
if self.matches(path, file_mode) {
|
||||||
|
Some(self.match_type())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn entry_matches_exact(&self, path: &[u8], file_mode: Option<u32>) -> Option<MatchType> {
|
||||||
|
if self.matches_exact(path, file_mode) {
|
||||||
|
Some(self.match_type())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This provides `matches` and `matches_exact` methods to lists of `MatchEntry`s.
|
/// This provides `matches` and `matches_exact` methods to lists of `MatchEntry`s.
|
||||||
///
|
///
|
||||||
/// Technically this is implemented for anything you can turn into a `DoubleEndedIterator` over
|
/// Technically this is implemented for anything you can turn into a `DoubleEndedIterator` over
|
||||||
@ -332,35 +350,39 @@ impl MatchListEntry for &'_ MatchEntry {
|
|||||||
///
|
///
|
||||||
/// In practice this means you can use it with slices or references to `Vec` or `VecDeque` etc.
|
/// In practice this means you can use it with slices or references to `Vec` or `VecDeque` etc.
|
||||||
/// This makes it easier to use slices over entries or references to entries.
|
/// This makes it easier to use slices over entries or references to entries.
|
||||||
pub trait MatchList: Sized {
|
pub trait MatchList {
|
||||||
/// Check whether this list contains anything matching a prefix of the specified path, and the
|
/// Check whether this list contains anything matching a prefix of the specified path, and the
|
||||||
/// specified file mode.
|
/// specified file mode.
|
||||||
fn matches<T: AsRef<[u8]>>(self, path: T, file_mode: Option<u32>) -> Option<MatchType> {
|
fn matches<T: AsRef<[u8]>>(&self, path: T, file_mode: Option<u32>) -> Option<MatchType> {
|
||||||
self.matches_do(path.as_ref(), file_mode)
|
self.matches_do(path.as_ref(), file_mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn matches_do(self, path: &[u8], file_mode: Option<u32>) -> Option<MatchType>;
|
fn matches_do(&self, path: &[u8], file_mode: Option<u32>) -> Option<MatchType>;
|
||||||
|
|
||||||
/// Check whether this list contains anything exactly matching the path and mode.
|
/// Check whether this list contains anything exactly matching the path and mode.
|
||||||
fn matches_exact<T: AsRef<[u8]>>(
|
fn matches_exact<T: AsRef<[u8]>>(
|
||||||
self,
|
&self,
|
||||||
path: T,
|
path: T,
|
||||||
file_mode: Option<u32>,
|
file_mode: Option<u32>,
|
||||||
) -> Option<MatchType> {
|
) -> Option<MatchType> {
|
||||||
self.matches_exact_do(path.as_ref(), file_mode)
|
self.matches_exact_do(path.as_ref(), file_mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn matches_exact_do(self, path: &[u8], file_mode: Option<u32>) -> Option<MatchType>;
|
fn matches_exact_do(&self, path: &[u8], file_mode: Option<u32>) -> Option<MatchType>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> MatchList for T
|
impl<'a, T> MatchList for T
|
||||||
where
|
where
|
||||||
T: IntoIterator,
|
T: 'a + ?Sized,
|
||||||
<T as IntoIterator>::IntoIter: DoubleEndedIterator,
|
&'a T: IntoIterator,
|
||||||
<T as IntoIterator>::Item: MatchListEntry,
|
<&'a T as IntoIterator>::IntoIter: DoubleEndedIterator,
|
||||||
|
<&'a T as IntoIterator>::Item: MatchListEntry,
|
||||||
{
|
{
|
||||||
fn matches_do(self, path: &[u8], file_mode: Option<u32>) -> Option<MatchType> {
|
fn matches_do(&self, path: &[u8], file_mode: Option<u32>) -> Option<MatchType> {
|
||||||
for m in self.into_iter().rev() {
|
// This is an &self method on a `T where T: 'a`.
|
||||||
|
let this: &'a Self = unsafe { std::mem::transmute(self) };
|
||||||
|
|
||||||
|
for m in this.into_iter().rev() {
|
||||||
if let Some(mt) = m.entry_matches(path, file_mode) {
|
if let Some(mt) = m.entry_matches(path, file_mode) {
|
||||||
return Some(mt);
|
return Some(mt);
|
||||||
}
|
}
|
||||||
@ -369,8 +391,11 @@ where
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn matches_exact_do(self, path: &[u8], file_mode: Option<u32>) -> Option<MatchType> {
|
fn matches_exact_do(&self, path: &[u8], file_mode: Option<u32>) -> Option<MatchType> {
|
||||||
for m in self.into_iter().rev() {
|
// This is an &self method on a `T where T: 'a`.
|
||||||
|
let this: &'a Self = unsafe { std::mem::transmute(self) };
|
||||||
|
|
||||||
|
for m in this.into_iter().rev() {
|
||||||
if let Some(mt) = m.entry_matches_exact(path, file_mode) {
|
if let Some(mt) = m.entry_matches_exact(path, file_mode) {
|
||||||
return Some(mt);
|
return Some(mt);
|
||||||
}
|
}
|
||||||
@ -396,6 +421,9 @@ fn assert_containers_implement_match_list() {
|
|||||||
|
|
||||||
let list: Vec<&MatchEntry> = vec.iter().collect();
|
let list: Vec<&MatchEntry> = vec.iter().collect();
|
||||||
assert_eq!(list.matches("asdf", None), Some(MatchType::Include));
|
assert_eq!(list.matches("asdf", None), Some(MatchType::Include));
|
||||||
|
|
||||||
|
let list: &[&MatchEntry] = &list[..];
|
||||||
|
assert_eq!(list.matches("asdf", None), Some(MatchType::Include));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user