use crate::error::CliError;
use std::path::PathBuf;
#[derive(Debug, Clone)]
pub struct FileResult<T> {
pub path: PathBuf,
pub result: Result<T, CliError>,
}
impl<T> FileResult<T> {
pub fn success(path: PathBuf, value: T) -> Self {
Self {
path,
result: Ok(value),
}
}
#[must_use]
pub fn failure(path: PathBuf, error: CliError) -> Self {
Self {
path,
result: Err(error),
}
}
pub fn is_success(&self) -> bool {
self.result.is_ok()
}
pub fn is_failure(&self) -> bool {
self.result.is_err()
}
}
#[derive(Debug, Clone)]
pub struct BatchResults<T> {
pub results: Vec<FileResult<T>>,
pub elapsed_ms: u128,
}
impl<T> BatchResults<T> {
#[must_use]
pub fn new(results: Vec<FileResult<T>>, elapsed_ms: u128) -> Self {
Self {
results,
elapsed_ms,
}
}
#[must_use]
pub fn total_files(&self) -> usize {
self.results.len()
}
#[must_use]
pub fn success_count(&self) -> usize {
self.results.iter().filter(|r| r.is_success()).count()
}
#[must_use]
pub fn failure_count(&self) -> usize {
self.results.iter().filter(|r| r.is_failure()).count()
}
#[must_use]
pub fn all_succeeded(&self) -> bool {
self.results.iter().all(FileResult::is_success)
}
#[must_use]
pub fn has_failures(&self) -> bool {
self.results.iter().any(FileResult::is_failure)
}
pub fn successes(&self) -> impl Iterator<Item = &FileResult<T>> {
self.results.iter().filter(|r| r.is_success())
}
pub fn failures(&self) -> impl Iterator<Item = &FileResult<T>> {
self.results.iter().filter(|r| r.is_failure())
}
#[must_use]
pub fn throughput(&self) -> f64 {
if self.elapsed_ms == 0 {
0.0
} else {
(self.total_files() as f64) / (self.elapsed_ms as f64 / 1000.0)
}
}
}