Add Stream::extract_with() and Stream::par_extract_with() methods which run a function for each Node in an archive
This commit is contained in:
parent
c60e385dd0
commit
1740dcb79c
@ -79,6 +79,27 @@ impl<R: Read + Send> Stream<R> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Extracts an archive, running the function `f` for each node
|
||||
/// # Errors
|
||||
/// Returns `crate::Error` if io fails or several other error conditions
|
||||
pub fn extract_with<F>(
|
||||
&mut self,
|
||||
prefix: Option<&str>,
|
||||
uid: Option<u32>,
|
||||
gid: Option<u32>,
|
||||
f: F,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
F: FnOnce(Node, Option<u32>, Option<u32>) + Copy,
|
||||
{
|
||||
for node in self {
|
||||
let node = node?;
|
||||
node.extract(prefix, uid, gid)?;
|
||||
f(node, uid, gid);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
/// Extracts and archive in parallel
|
||||
/// # Errors
|
||||
@ -130,4 +151,62 @@ impl<R: Read + Send> Stream<R> {
|
||||
sender.send(Message::Eof).map_err(|_| Error::SenderError)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
/// Extracts and archive in parallel and runs the passed in function for
|
||||
/// each `Node`
|
||||
/// # Errors
|
||||
/// Returns `crate::Error` if io fails or several other error conditions
|
||||
pub fn par_extract_with<F>(
|
||||
&mut self,
|
||||
prefix: Option<&str>,
|
||||
uid: Option<u32>,
|
||||
gid: Option<u32>,
|
||||
sender: &Sender<Message>,
|
||||
f: F,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
F: FnOnce(Node, Option<u32>, Option<u32>) + Copy + Send + Sync,
|
||||
{
|
||||
let s = sender.clone();
|
||||
self.into_iter().par_bridge().try_for_each_with(s, |s, n| {
|
||||
let n = n?;
|
||||
n.extract(prefix, uid, gid)?;
|
||||
match n.filetype {
|
||||
FileType::Normal(ref f) => {
|
||||
s.send(Message::FileExtracted {
|
||||
name: n.name.clone(),
|
||||
size: f.len,
|
||||
})
|
||||
.map_err(|_| Error::SenderError)?;
|
||||
}
|
||||
FileType::SoftLink(ref t) | FileType::HardLink(ref t) => {
|
||||
s.send(Message::LinkCreated {
|
||||
name: n.name.clone(),
|
||||
target: t.clone(),
|
||||
})
|
||||
.map_err(|_| Error::SenderError)?;
|
||||
}
|
||||
FileType::Directory => {
|
||||
s.send(Message::DirectoryCreated {
|
||||
name: n.name.clone(),
|
||||
})
|
||||
.map_err(|_| Error::SenderError)?;
|
||||
}
|
||||
FileType::Block(_) | FileType::Character(_) | FileType::Fifo => {
|
||||
s.send(Message::DeviceCreated {
|
||||
name: n.name.clone(),
|
||||
})
|
||||
.map_err(|_| Error::SenderError)?;
|
||||
}
|
||||
FileType::Eof => {
|
||||
s.send(Message::Eof).map_err(|_| Error::SenderError)?;
|
||||
}
|
||||
}
|
||||
f(n, uid, gid);
|
||||
Ok::<(), Error>(())
|
||||
})?;
|
||||
sender.send(Message::Eof).map_err(|_| Error::SenderError)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user