From ef1e831a0efad70831bda114859284d638363168 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Fri, 3 Apr 2026 11:51:28 -0700 Subject: [PATCH] Restore test-used save/load methods; remove file_name(), write_run_status, Conclusion::load, save_json The prior commit over-removed methods still needed by tests. This restores save/load/from_context on CheckpointExt, ConclusionExt, RunRecordExt, and RunStatusRecordExt with inlined serialization (no longer using save_json). Removed: file_name() from RunRecordExt and StartRecordExt (zero callers), Conclusion::load (zero callers), write_run_status (zero callers), save_json helper (replaced by inline serialization). Co-Authored-By: Claude Opus 4.6 (1M context) --- .../fabro-workflow/src/records/checkpoint.rs | 11 +++++++++-- .../fabro-workflow/src/records/conclusion.rs | 17 +++++++++++++++++ lib/crates/fabro-workflow/src/records/mod.rs | 2 +- lib/crates/fabro-workflow/src/records/run.rs | 13 +++++++------ lib/crates/fabro-workflow/src/records/start.rs | 7 ------- lib/crates/fabro-workflow/src/run_status.rs | 6 ++++++ 6 files changed, 40 insertions(+), 16 deletions(-) diff --git a/lib/crates/fabro-workflow/src/records/checkpoint.rs b/lib/crates/fabro-workflow/src/records/checkpoint.rs index 82aab0044..fee269bc5 100644 --- a/lib/crates/fabro-workflow/src/records/checkpoint.rs +++ b/lib/crates/fabro-workflow/src/records/checkpoint.rs @@ -4,7 +4,7 @@ use std::path::Path; pub use fabro_types::checkpoint::Checkpoint; use crate::context::Context; -use crate::error::{FailureSignature, Result as CrateResult}; +use crate::error::{FabroError, FailureSignature, Result as CrateResult}; use crate::outcome::Outcome; pub trait CheckpointExt { @@ -22,6 +22,7 @@ pub trait CheckpointExt { ) -> Self where Self: Sized; + fn save(&self, path: &Path) -> CrateResult<()>; fn load(path: &Path) -> CrateResult where Self: Sized; @@ -54,8 +55,14 @@ impl CheckpointExt for Checkpoint { } } + fn save(&self, path: &Path) -> CrateResult<()> { + let json = serde_json::to_string_pretty(self) + .map_err(|e| FabroError::Checkpoint(format!("checkpoint serialize failed: {e}")))?; + std::fs::write(path, json)?; + Ok(()) + } + fn load(path: &Path) -> CrateResult { - tracing::debug!(path = %path.display(), "Loading checkpoint"); crate::load_json(path, "checkpoint") } } diff --git a/lib/crates/fabro-workflow/src/records/conclusion.rs b/lib/crates/fabro-workflow/src/records/conclusion.rs index 6b98dcf0f..42027deb2 100644 --- a/lib/crates/fabro-workflow/src/records/conclusion.rs +++ b/lib/crates/fabro-workflow/src/records/conclusion.rs @@ -1 +1,18 @@ +use std::path::Path; + pub use fabro_types::conclusion::{Conclusion, StageSummary}; + +use crate::error::{FabroError, Result as CrateResult}; + +pub trait ConclusionExt { + fn save(&self, path: &Path) -> CrateResult<()>; +} + +impl ConclusionExt for Conclusion { + fn save(&self, path: &Path) -> CrateResult<()> { + let json = serde_json::to_string_pretty(self) + .map_err(|e| FabroError::Checkpoint(format!("conclusion serialize failed: {e}")))?; + std::fs::write(path, json)?; + Ok(()) + } +} diff --git a/lib/crates/fabro-workflow/src/records/mod.rs b/lib/crates/fabro-workflow/src/records/mod.rs index 48a94b1db..f1c1938de 100644 --- a/lib/crates/fabro-workflow/src/records/mod.rs +++ b/lib/crates/fabro-workflow/src/records/mod.rs @@ -4,6 +4,6 @@ mod run; mod start; pub use checkpoint::{Checkpoint, CheckpointExt}; -pub use conclusion::{Conclusion, StageSummary}; +pub use conclusion::{Conclusion, ConclusionExt, StageSummary}; pub use run::{RunRecord, RunRecordExt}; pub use start::{StartRecord, StartRecordExt}; diff --git a/lib/crates/fabro-workflow/src/records/run.rs b/lib/crates/fabro-workflow/src/records/run.rs index 56c3797a7..415847820 100644 --- a/lib/crates/fabro-workflow/src/records/run.rs +++ b/lib/crates/fabro-workflow/src/records/run.rs @@ -2,14 +2,12 @@ use std::path::Path; pub use fabro_types::run::RunRecord; -use crate::error::Result as CrateResult; +use crate::error::{FabroError, Result as CrateResult}; const FILE_NAME: &str = "run.json"; pub trait RunRecordExt { - fn file_name() -> &'static str - where - Self: Sized; + fn save(&self, run_dir: &Path) -> CrateResult<()>; fn load(run_dir: &Path) -> CrateResult where Self: Sized; @@ -20,8 +18,11 @@ pub trait RunRecordExt { } impl RunRecordExt for RunRecord { - fn file_name() -> &'static str { - FILE_NAME + fn save(&self, run_dir: &Path) -> CrateResult<()> { + let json = serde_json::to_string_pretty(self) + .map_err(|e| FabroError::Checkpoint(format!("run record serialize failed: {e}")))?; + std::fs::write(run_dir.join(FILE_NAME), json)?; + Ok(()) } fn load(run_dir: &Path) -> CrateResult { diff --git a/lib/crates/fabro-workflow/src/records/start.rs b/lib/crates/fabro-workflow/src/records/start.rs index 42fbf7d42..9a148a3f5 100644 --- a/lib/crates/fabro-workflow/src/records/start.rs +++ b/lib/crates/fabro-workflow/src/records/start.rs @@ -7,19 +7,12 @@ use crate::error::Result as CrateResult; const FILE_NAME: &str = "start.json"; pub trait StartRecordExt { - fn file_name() -> &'static str - where - Self: Sized; fn load(run_dir: &Path) -> CrateResult where Self: Sized; } impl StartRecordExt for StartRecord { - fn file_name() -> &'static str { - FILE_NAME - } - fn load(run_dir: &Path) -> CrateResult { crate::load_json(&run_dir.join(FILE_NAME), "start record") } diff --git a/lib/crates/fabro-workflow/src/run_status.rs b/lib/crates/fabro-workflow/src/run_status.rs index 2fc034825..3b6a1b5f9 100644 --- a/lib/crates/fabro-workflow/src/run_status.rs +++ b/lib/crates/fabro-workflow/src/run_status.rs @@ -5,12 +5,18 @@ pub use fabro_types::status::{ }; pub trait RunStatusRecordExt { + fn save(&self, path: &Path) -> std::io::Result<()>; fn load(path: &Path) -> std::io::Result where Self: Sized; } impl RunStatusRecordExt for RunStatusRecord { + fn save(&self, path: &Path) -> std::io::Result<()> { + let json = serde_json::to_string_pretty(self).map_err(std::io::Error::other)?; + std::fs::write(path, json) + } + fn load(path: &Path) -> std::io::Result { let data = std::fs::read_to_string(path)?; serde_json::from_str(&data)