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

70 lines
1.8 KiB

//! 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,
},
};
use tokio::{
fs,
task::JoinHandle,
};
use futures::{
prelude::*,
future::BoxFuture,
};
/// Process a single file.
///
/// `path` is known to be a file at this point.
async fn process_single(state: Arc<state::State>, path: impl AsRef<Path>) -> eyre::Result<()>
{
let path = path.as_ref();
debug_assert!(path.is_file(), "process_single() expected a file, but {:?} is not one.", path);
let _g = state.lock().await;
debug!("{:?} Processing", path);
Ok(())
}
/// Process this path
///
/// This will not return until all its children finish too (if any)
pub async fn process<'a, P>(state: Arc<state::State>, path: P) -> eyre::Result<()>
where P: 'a + Send + AsRef<Path>
{
let path = path.as_ref();
if path.is_dir() {
let read = fs::read_dir(path).await?;
fn proc_dir(state: Arc<state::State>, mut read: fs::ReadDir) -> BoxFuture<'static, JoinHandle<Result<(), eyre::Report>>>
{
async move {
tokio::spawn(async move {
while let Some(entry) = read.next_entry().await?
{
process(Arc::clone(&state), entry.path()).await?;
}
Ok::<_, eyre::Report>(())
})
}.boxed()
}
let handle = proc_dir(state, read).await;
let res = handle.await
.wrap_err(eyre!("Child exited abnormally"))?;
res.wrap_err(eyre!("Failed to process children"))
} else if path.is_file() {
process_single(state, path).await
} else {
Err(eyre!("Invalid/unsupported FSO"))
}.with_section(|| format!("{:?}", path).header("Path was"))
}