use crate::progress::ProgressReporter;
use anyhow::Result;
#[derive(Debug, Clone)]
pub enum ScanStatus {
Pruneable(u64),
Clean,
NotFound,
#[allow(dead_code)]
PermissionDenied,
}
#[derive(Debug, Clone)]
pub struct ScanResult {
pub name: &'static str,
pub status: ScanStatus,
pub primary_target: Option<String>,
}
impl ScanResult {
pub fn new(name: &'static str, status: ScanStatus) -> Self {
Self {
name,
status,
primary_target: None,
}
}
pub fn with_target(mut self, target: impl Into<String>) -> Self {
self.primary_target = Some(target.into());
self
}
}
#[derive(Debug)]
pub struct CleanResult {
#[allow(dead_code)]
pub name: &'static str,
pub bytes_freed: u64,
}
#[derive(Debug)]
pub struct CleanCancelled;
impl std::fmt::Display for CleanCancelled {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "cleaning cancelled by user")
}
}
impl std::error::Error for CleanCancelled {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn scan_result_new_has_no_primary_target() {
let r = ScanResult::new("test", ScanStatus::Clean);
assert_eq!(r.name, "test");
assert!(matches!(r.status, ScanStatus::Clean));
assert!(r.primary_target.is_none());
}
#[test]
fn scan_result_with_target_sets_primary() {
let r = ScanResult::new("test", ScanStatus::Clean).with_target("/some/path");
assert_eq!(r.primary_target.as_deref(), Some("/some/path"));
}
}
pub trait Cleaner: Send + Sync {
fn name(&self) -> &'static str;
fn detect(&self) -> ScanResult;
fn clean(&self, dry_run: bool, reporter: &dyn ProgressReporter) -> Result<CleanResult>;
}