xchecker_engine/fixup/
phase.rs1use crate::phase::{NextStep, Phase, PhaseContext, PhaseMetadata, PhaseResult};
8use crate::status::artifact::{Artifact, ArtifactType};
9use anyhow::Result;
10
11use super::FixupMode;
12use super::parse::FixupParser;
13
14#[derive(Debug, Clone)]
20pub struct FixupPhase {
21 mode: FixupMode,
22}
23
24impl FixupPhase {
25 #[must_use]
27 pub const fn new_with_mode(mode: FixupMode) -> Self {
28 Self { mode }
29 }
30
31 #[must_use]
33 pub const fn new() -> Self {
34 Self {
35 mode: FixupMode::Preview,
36 }
37 }
38}
39
40impl Phase for FixupPhase {
41 fn id(&self) -> crate::types::PhaseId {
42 xchecker_utils::types::PhaseId::Fixup
43 }
44
45 fn deps(&self) -> &'static [xchecker_utils::types::PhaseId] {
46 &[xchecker_utils::types::PhaseId::Review]
48 }
49
50 fn can_resume(&self) -> bool {
51 true
52 }
53
54 fn prompt(&self, _ctx: &PhaseContext) -> String {
55 String::new()
58 }
59
60 fn make_packet(&self, _ctx: &PhaseContext) -> Result<crate::packet::Packet> {
61 let empty_content = String::new();
64 let blake3_hash = blake3::hash(empty_content.as_bytes()).to_hex().to_string();
65
66 let evidence = crate::types::PacketEvidence {
67 files: vec![],
68 max_bytes: 65536,
69 max_lines: 1200,
70 };
71
72 let budget_used = crate::packet::BudgetUsage::new(65536, 1200);
73
74 Ok(crate::packet::Packet::new(
75 empty_content,
76 blake3_hash,
77 evidence,
78 budget_used,
79 ))
80 }
81
82 fn postprocess(&self, raw: &str, ctx: &PhaseContext) -> Result<PhaseResult> {
83 let parser = FixupParser::new(self.mode, ctx.spec_dir.clone())?;
85
86 match parser.parse_diffs(raw) {
87 Ok(diffs) => {
88 let fixup_content = format!(
90 "# Fixup Report\n\nMode: {:?}\n\nParsed {} diff(s) from review output.\n",
91 self.mode,
92 diffs.len()
93 );
94
95 let fixup_artifact = Artifact {
96 name: "40-fixup.md".to_string(),
97 content: fixup_content.clone(),
98 artifact_type: ArtifactType::Markdown,
99 blake3_hash: blake3::hash(fixup_content.as_bytes()).to_hex().to_string(),
100 };
101
102 let artifacts = vec![fixup_artifact];
103
104 let metadata = PhaseMetadata::default();
106
107 Ok(PhaseResult {
108 artifacts,
109 next_step: NextStep::Continue, metadata,
111 })
112 }
113 Err(e) => Err(e.into()),
114 }
115 }
116}
117
118impl Default for FixupPhase {
119 fn default() -> Self {
120 Self::new()
121 }
122}