use super::error::PodProductsError;
use crate::pod::run::manifest::RunManifest;
use std::io::Write;
pub struct ManifestWriter;
impl ManifestWriter {
pub fn write<W: Write>(w: &mut W, manifest: &RunManifest) -> Result<(), PodProductsError> {
let json = manifest.to_json_pretty()?;
w.write_all(json.as_bytes())?;
w.write_all(b"\n")?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
fn sample_manifest() -> RunManifest {
RunManifest {
run_id: "00000000-0000-0000-0000-000000000000".into(),
tool_version: "siderust 0.8.0".into(),
config_sha256: "0".repeat(64),
inputs: vec![],
outputs: vec![],
started_at: "2026-01-01T00:00:00Z".into(),
finished_at: "2026-01-01T00:00:01Z".into(),
}
}
#[test]
fn write_produces_valid_json() {
let mut buf = Vec::new();
ManifestWriter::write(&mut buf, &sample_manifest()).unwrap();
let text = String::from_utf8(buf).unwrap();
let v: serde_json::Value = serde_json::from_str(&text).unwrap();
assert_eq!(
v["run_id"].as_str().unwrap(),
"00000000-0000-0000-0000-000000000000"
);
}
#[test]
fn write_is_deterministic() {
let mut a = Vec::new();
let mut b = Vec::new();
ManifestWriter::write(&mut a, &sample_manifest()).unwrap();
ManifestWriter::write(&mut b, &sample_manifest()).unwrap();
assert_eq!(a, b);
}
#[test]
fn write_ends_with_newline() {
let mut buf = Vec::new();
ManifestWriter::write(&mut buf, &sample_manifest()).unwrap();
assert!(buf.ends_with(b"\n"));
}
#[test]
fn write_contains_all_required_fields() {
let mut buf = Vec::new();
ManifestWriter::write(&mut buf, &sample_manifest()).unwrap();
let text = String::from_utf8(buf).unwrap();
for field in [
"run_id",
"tool_version",
"config_sha256",
"inputs",
"outputs",
"started_at",
"finished_at",
] {
assert!(text.contains(field), "missing field: {field}");
}
}
}