use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum Action {
Created,
Updated,
Skipped,
Modified,
Missing,
Removed,
}
impl Action {
pub fn as_str(&self) -> &'static str {
match self {
Action::Created => "CREATED",
Action::Updated => "UPDATED",
Action::Skipped => "SKIPPED",
Action::Modified => "MODIFIED",
Action::Missing => "MISSING",
Action::Removed => "REMOVED",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileEntry {
pub path: String,
pub action: Action,
pub sha256: String,
pub expected_sha256: Option<String>,
pub size_bytes: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Summary {
pub created: usize,
pub updated: usize,
pub skipped: usize,
pub modified: usize,
pub missing: usize,
pub removed: usize,
}
impl Summary {
pub fn from_entries(entries: &[FileEntry]) -> Self {
let mut s = Self {
created: 0,
updated: 0,
skipped: 0,
modified: 0,
missing: 0,
removed: 0,
};
for e in entries {
match e.action {
Action::Created => s.created += 1,
Action::Updated => s.updated += 1,
Action::Skipped => s.skipped += 1,
Action::Modified => s.modified += 1,
Action::Missing => s.missing += 1,
Action::Removed => s.removed += 1,
}
}
s
}
pub fn has_drift(&self) -> bool {
self.modified > 0 || self.missing > 0
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Report {
pub status: String,
pub command: String,
pub files: Vec<FileEntry>,
pub summary: Summary,
pub cli_version: String,
pub schema_version: u32,
pub duration_ms: u64,
pub plugin_version: String,
}
impl Report {
pub fn new(command: impl Into<String>, plugin_version: impl Into<String>) -> Self {
Self {
status: "ok".to_string(),
command: command.into(),
files: Vec::new(),
summary: Summary {
created: 0,
updated: 0,
skipped: 0,
modified: 0,
missing: 0,
removed: 0,
},
cli_version: env!("CARGO_PKG_VERSION").to_string(),
schema_version: 1,
duration_ms: 0,
plugin_version: plugin_version.into(),
}
}
pub fn finalize(&mut self) {
self.summary = Summary::from_entries(&self.files);
if self.summary.has_drift() && self.status == "ok" {
self.status = "drift".to_string();
}
}
pub fn set_error(&mut self, msg: impl Into<String>) {
self.status = format!("error: {}", msg.into());
}
}
pub mod json;
pub mod ndjson;
pub mod text;