use std::{env, fs, io::Result, path::PathBuf};
use crate::config::{downloads_dir, model_cache_dir};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "cli", derive(clap::Subcommand))]
pub enum Drain {
All,
Oci,
Lib,
Smithy,
Downloads,
}
impl IntoIterator for &Drain {
type Item = PathBuf;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
let paths = match self {
Drain::All => vec![
env::temp_dir().join("wasmcloudcache"),
env::temp_dir().join("wasmcloud_ocicache"),
model_cache_dir().unwrap_or_default(),
downloads_dir().unwrap_or_default(),
],
Drain::Lib => vec![env::temp_dir().join("wasmcloudcache")],
Drain::Oci => vec![env::temp_dir().join("wasmcloud_ocicache")],
Drain::Smithy => vec![model_cache_dir().unwrap_or_default()],
Drain::Downloads => vec![downloads_dir().unwrap_or_default()],
};
paths.into_iter()
}
}
impl Drain {
pub fn drain(self) -> Result<Vec<PathBuf>> {
self.into_iter()
.filter(|path| path.exists())
.map(remove_dir_contents)
.collect::<Result<Vec<PathBuf>>>()
}
}
fn remove_dir_contents(path: PathBuf) -> Result<PathBuf> {
for entry in fs::read_dir(&path)? {
let path = entry?.path();
if path.is_dir() {
fs::remove_dir_all(&path)?;
} else if path.is_file() {
fs::remove_file(&path)?;
}
}
Ok(path)
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_dir_clean() {
let tempdir = tempfile::tempdir().expect("Unable to create tempdir");
let subdir = tempdir.path().join("foobar");
fs::create_dir(&subdir).unwrap();
{
fs::File::create(subdir.join("baz")).unwrap();
fs::File::create(tempdir.path().join("baz")).unwrap();
}
remove_dir_contents(tempdir.path().to_owned())
.expect("Shouldn't get an error when cleaning files");
assert!(
tempdir
.path()
.read_dir()
.expect("Top level dir should still exist")
.next()
.is_none(),
"Directory should be empty"
);
}
}