use anyhow::Result;
use exarch_core::ArchiveManifest;
use exarch_core::CreationReport;
use exarch_core::ExtractionReport;
use exarch_core::VerificationReport;
use serde::Serialize;
use std::path::Path;
pub trait OutputFormatter {
fn format_extraction_result(&self, report: &ExtractionReport) -> Result<()>;
fn format_creation_result(&self, output_path: &Path, report: &CreationReport) -> Result<()>;
fn format_manifest_short(&self, manifest: &ArchiveManifest) -> Result<()>;
fn format_manifest_long(&self, manifest: &ArchiveManifest, human_readable: bool) -> Result<()>;
fn format_verification_report(&self, report: &VerificationReport) -> Result<()>;
fn format_error(&self, operation: &str, error: &anyhow::Error);
#[allow(dead_code)]
fn format_success(&self, message: &str);
#[allow(dead_code)]
fn format_warning(&self, message: &str);
}
#[derive(Debug, Serialize)]
pub struct JsonOutput<T> {
pub operation: String,
pub status: Status,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<T>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<JsonError>,
}
#[derive(Debug, Serialize)]
pub struct JsonPartialReport {
pub files_extracted: usize,
pub directories_created: usize,
pub symlinks_created: usize,
pub bytes_written: u64,
}
#[derive(Debug, Serialize)]
pub struct JsonError {
pub kind: String,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub partial_report: Option<JsonPartialReport>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum Status {
Success,
#[allow(dead_code)]
Error,
}
impl<T: Serialize> JsonOutput<T> {
pub fn success(operation: impl Into<String>, data: T) -> Self {
Self {
operation: operation.into(),
status: Status::Success,
data: Some(data),
error: None,
}
}
pub fn error(
operation: impl Into<String>,
kind: impl Into<String>,
message: impl Into<String>,
) -> JsonOutput<()> {
JsonOutput {
operation: operation.into(),
status: Status::Error,
data: None,
error: Some(JsonError {
kind: kind.into(),
message: message.into(),
partial_report: None,
}),
}
}
pub fn error_with_partial(
operation: impl Into<String>,
kind: impl Into<String>,
message: impl Into<String>,
partial_report: JsonPartialReport,
) -> JsonOutput<()> {
JsonOutput {
operation: operation.into(),
status: Status::Error,
data: None,
error: Some(JsonError {
kind: kind.into(),
message: message.into(),
partial_report: Some(partial_report),
}),
}
}
}