use serde::Serialize;
use std::time::Duration;
#[derive(Clone, Debug, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum CommandStatus {
Success,
Failed,
Skipped,
}
#[derive(Clone, Debug, Serialize)]
pub struct CommandResult {
pub command: String,
pub status: CommandStatus,
pub duration_ms: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub output: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
}
impl CommandResult {
pub fn success(command: impl Into<String>, duration: Duration, output: Option<String>) -> Self {
Self {
command: command.into(),
status: CommandStatus::Success,
duration_ms: duration.as_millis() as u64,
output,
error: None,
}
}
pub fn failed(command: impl Into<String>, duration: Duration, error: impl Into<String>) -> Self {
Self {
command: command.into(),
status: CommandStatus::Failed,
duration_ms: duration.as_millis() as u64,
output: None,
error: Some(error.into()),
}
}
pub fn skipped(command: impl Into<String>, reason: impl Into<String>) -> Self {
Self {
command: command.into(),
status: CommandStatus::Skipped,
duration_ms: 0,
output: None,
error: Some(reason.into()),
}
}
}
pub fn emit_json<T: Serialize>(value: &T) {
if let Ok(json) = serde_json::to_string_pretty(value) {
println!("{}", json);
}
}
pub fn emit_result(result: &CommandResult) {
emit_json(result);
}
#[derive(Clone, Debug, Serialize)]
pub struct BatchResult {
pub total: usize,
pub succeeded: usize,
pub failed: usize,
pub skipped: usize,
pub duration_ms: u64,
pub results: Vec<CommandResult>,
}
impl BatchResult {
pub fn from_results(results: Vec<CommandResult>, total_duration: Duration) -> Self {
let succeeded = results
.iter()
.filter(|r| matches!(r.status, CommandStatus::Success))
.count();
let failed = results
.iter()
.filter(|r| matches!(r.status, CommandStatus::Failed))
.count();
let skipped = results
.iter()
.filter(|r| matches!(r.status, CommandStatus::Skipped))
.count();
Self {
total: results.len(),
succeeded,
failed,
skipped,
duration_ms: total_duration.as_millis() as u64,
results,
}
}
}