You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
videl/src/delete.rs

81 lines
2.4 KiB

4 years ago
//! Handle deletion
//!
//! # Handling paths
//! Deletion of single files is trivial, deletion of directories is not as trivial.
//! Other types of filesystem object are ignored.
//!
//! ## Directories
//! With directories the deletion processes all files containing recursively.
//! See `restore` for restoration of directories
use super::*;
use std::{
path::{
Path,
},
};
4 years ago
use tokio::{
fs,
task::JoinHandle,
4 years ago
};
use futures::{
prelude::*,
future::BoxFuture,
};
4 years ago
/// Process a single file.
///
/// `path` is known to be a file at this point.
async fn process_single(state: Arc<state::State>, logger: &mut progress::logging::Logger, path: impl AsRef<Path>) -> eyre::Result<()>
4 years ago
{
4 years ago
let path = path.as_ref();
debug_assert!(path.is_file(), "process_single() expected a file, but {:?} is not one.", path);
4 years ago
4 years ago
let _g = state.lock().await;
trace!(logger => "{:?} Processing", path);
4 years ago
4 years ago
Ok(())
}
/// Process this path
///
/// This will not return until all its children finish too (if any)
pub async fn process<'a, P, L>(state: Arc<state::State>, mut logger: L, path: P) -> eyre::Result<()>
where P: 'a + Send + AsRef<Path>,
L: std::borrow::BorrowMut<progress::logging::Logger>
4 years ago
{
let path = path.as_ref();
4 years ago
if path.is_dir() {
let read = fs::read_dir(path).await?;
fn proc_dir(state: Arc<state::State>, logger: &mut progress::logging::Logger, mut read: fs::ReadDir) -> BoxFuture<'static, JoinHandle<Result<(), eyre::Report>>>
{
let mut logger = logger.clone();
async move {
tokio::spawn(async move {
while let Some(entry) = read.next_entry().await?
{
let path = entry.path();
if let Err(error) = process(Arc::clone(&state), &mut logger, &path).await {
{
let err = &error;
let path = &path; //TODO: Get these macros to stop moving
error!(logger => "{:?} child failed: {}", path, err);
}
debug!(logger => "Error for {:?}: {:?}", path, error);
}
}
Ok::<_, eyre::Report>(())
})
}.boxed()
}
let handle = proc_dir(state, logger.borrow_mut(), read).await;
let res = handle.await
.wrap_err(eyre!("Child exited abnormally"))?;
res.wrap_err(eyre!("Failed to process children"))
4 years ago
} else if path.is_file() {
process_single(state, logger.borrow_mut(), path).await
4 years ago
} else {
Err(eyre!("Invalid/unsupported FSO"))
}.with_section(|| format!("{:?}", path).header("Path was"))
4 years ago
}