use anyhow::Result;
use async_trait::async_trait;
use s3rm_rs::{
Config, DeletionPipeline, EventCallback, EventData, EventType, FilterCallback, S3Object,
build_config_from_args, create_pipeline_cancellation_token,
};
struct SizeFilter {
min_bytes: i64,
}
#[async_trait]
impl FilterCallback for SizeFilter {
async fn filter(&mut self, object: &S3Object) -> Result<bool> {
Ok(object.size() >= self.min_bytes)
}
}
struct LoggingEventHandler;
#[async_trait]
impl EventCallback for LoggingEventHandler {
async fn on_event(&mut self, event: EventData) {
if event.event_type.contains(EventType::DELETE_COMPLETE) {
println!(
" Deleted: {} ({} bytes)",
event.key.as_deref().unwrap_or("?"),
event.size.unwrap_or(0),
);
}
if event.event_type.contains(EventType::DELETE_FAILED) {
eprintln!(
" FAILED: {} - {}",
event.key.as_deref().unwrap_or("?"),
event.error_message.as_deref().unwrap_or("unknown"),
);
}
if event.event_type.contains(EventType::PIPELINE_END) {
println!("Pipeline finished.");
}
}
}
#[tokio::main]
async fn main() -> Result<()> {
let mut config: Config =
build_config_from_args(std::env::args_os()).map_err(|e| anyhow::anyhow!(e))?;
config
.filter_manager
.register_callback(SizeFilter { min_bytes: 1024 });
config.event_manager.register_callback(
EventType::ALL_EVENTS,
LoggingEventHandler,
false, );
let token = create_pipeline_cancellation_token();
let mut pipeline = DeletionPipeline::new(config, token).await;
pipeline.close_stats_sender();
pipeline.run().await;
if pipeline.has_error() {
let errors = pipeline.get_errors_and_consume().unwrap();
for err in &errors {
eprintln!("Pipeline error: {err:?}");
}
}
let stats = pipeline.get_deletion_stats();
println!(
"Summary: {} deleted ({} bytes), {} failed, {:.1}s",
stats.stats_deleted_objects,
stats.stats_deleted_bytes,
stats.stats_failed_objects,
stats.duration.as_secs_f64(),
);
Ok(())
}