opencode_ralph_loop_cli/output/
mod.rs1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
4#[serde(rename_all = "lowercase")]
5pub enum Action {
6 Created,
7 Updated,
8 Skipped,
9 Modified,
10 Missing,
11 Removed,
12}
13
14impl Action {
15 pub fn as_str(&self) -> &'static str {
16 match self {
17 Action::Created => "CREATED",
18 Action::Updated => "UPDATED",
19 Action::Skipped => "SKIPPED",
20 Action::Modified => "MODIFIED",
21 Action::Missing => "MISSING",
22 Action::Removed => "REMOVED",
23 }
24 }
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct FileEntry {
29 pub path: String,
30 pub action: Action,
31 pub sha256: String,
32 pub expected_sha256: Option<String>,
33 pub size_bytes: u64,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct Summary {
38 pub created: usize,
39 pub updated: usize,
40 pub skipped: usize,
41 pub modified: usize,
42 pub missing: usize,
43 pub removed: usize,
44}
45
46impl Summary {
47 pub fn from_entries(entries: &[FileEntry]) -> Self {
48 let mut s = Self {
49 created: 0,
50 updated: 0,
51 skipped: 0,
52 modified: 0,
53 missing: 0,
54 removed: 0,
55 };
56 for e in entries {
57 match e.action {
58 Action::Created => s.created += 1,
59 Action::Updated => s.updated += 1,
60 Action::Skipped => s.skipped += 1,
61 Action::Modified => s.modified += 1,
62 Action::Missing => s.missing += 1,
63 Action::Removed => s.removed += 1,
64 }
65 }
66 s
67 }
68
69 pub fn has_drift(&self) -> bool {
70 self.modified > 0 || self.missing > 0
71 }
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct Report {
76 pub status: String,
77 pub command: String,
78 pub files: Vec<FileEntry>,
79 pub summary: Summary,
80 pub cli_version: String,
81 pub schema_version: u32,
82 pub duration_ms: u64,
83 pub plugin_version: String,
84}
85
86impl Report {
87 pub fn new(command: impl Into<String>, plugin_version: impl Into<String>) -> Self {
88 Self {
89 status: "ok".to_string(),
90 command: command.into(),
91 files: Vec::new(),
92 summary: Summary {
93 created: 0,
94 updated: 0,
95 skipped: 0,
96 modified: 0,
97 missing: 0,
98 removed: 0,
99 },
100 cli_version: env!("CARGO_PKG_VERSION").to_string(),
101 schema_version: 1,
102 duration_ms: 0,
103 plugin_version: plugin_version.into(),
104 }
105 }
106
107 pub fn finalize(&mut self) {
108 self.summary = Summary::from_entries(&self.files);
109 if self.summary.has_drift() && self.status == "ok" {
110 self.status = "drift".to_string();
111 }
112 }
113
114 pub fn set_error(&mut self, msg: impl Into<String>) {
115 self.status = format!("error: {}", msg.into());
116 }
117}
118
119pub mod json;
120pub mod ndjson;
121pub mod text;