tools/fs: add FileIterOps trait and FileTypeFilter
FileIterOps will provide operations on file entry iterators. For now this provides a file type filter. Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
1db416150d
commit
23fba9d777
|
@ -4,7 +4,7 @@ use std::borrow::{Borrow, BorrowMut};
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
|
|
||||||
use failure::Error;
|
use failure::*;
|
||||||
use nix::dir;
|
use nix::dir;
|
||||||
use nix::dir::Dir;
|
use nix::dir::Dir;
|
||||||
|
|
||||||
|
@ -125,3 +125,65 @@ pub fn scan_subdir<'a, P: ?Sized + nix::NixPath>(
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper trait to provide a combinators for directory entry iterators.
|
||||||
|
pub trait FileIterOps<T, E>
|
||||||
|
where
|
||||||
|
Self: Sized + Iterator<Item = Result<T, E>>,
|
||||||
|
T: Borrow<dir::Entry>,
|
||||||
|
E: Into<Error> + Send + Sync,
|
||||||
|
{
|
||||||
|
/// Filter by file type. This is more convenient than using the `filter` method alone as this
|
||||||
|
/// also includes error handling and handling of files without a type (via an error).
|
||||||
|
fn filter_file_type(self, ty: dir::Type) -> FileTypeFilter<Self, T, E> {
|
||||||
|
FileTypeFilter { inner: self, ty }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I, T, E> FileIterOps<T, E> for I
|
||||||
|
where
|
||||||
|
I: Iterator<Item = Result<T, E>>,
|
||||||
|
T: Borrow<dir::Entry>,
|
||||||
|
E: Into<Error> + Send + Sync,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This filters files from its inner iterator by a file type. Files with no type produce an error.
|
||||||
|
pub struct FileTypeFilter<I, T, E>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = Result<T, E>>,
|
||||||
|
T: Borrow<dir::Entry>,
|
||||||
|
E: Into<Error> + Send + Sync,
|
||||||
|
{
|
||||||
|
inner: I,
|
||||||
|
ty: nix::dir::Type,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I, T, E> Iterator for FileTypeFilter<I, T, E>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = Result<T, E>>,
|
||||||
|
T: Borrow<dir::Entry>,
|
||||||
|
E: Into<Error> + Send + Sync,
|
||||||
|
{
|
||||||
|
type Item = Result<T, Error>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
loop {
|
||||||
|
let item = self.inner.next()?.map_err(|e| e.into());
|
||||||
|
match item {
|
||||||
|
Ok(ref entry) => match entry.borrow().file_type() {
|
||||||
|
Some(ty) => {
|
||||||
|
if ty == self.ty {
|
||||||
|
return Some(item);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => return Some(Err(format_err!("unable to detect file type"))),
|
||||||
|
},
|
||||||
|
Err(_) => return Some(item),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue