use std::io::Write;
use std::path::Path;
pub fn write_durable(tmp_path: &Path, final_path: &Path, bytes: &[u8]) -> std::io::Result<()> {
{
let mut f = std::fs::File::create(tmp_path)?;
f.write_all(bytes)?;
f.sync_all()?;
}
std::fs::rename(tmp_path, final_path)?;
if let Some(dir) = final_path.parent() {
if let Ok(d) = std::fs::File::open(dir) {
let _ = d.sync_all();
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn write_durable_round_trips_and_replaces_atomically() {
let dir = tempfile::tempdir().unwrap();
let path = dir.path().join("state.json");
let tmp = dir.path().join("state.json.tmp");
write_durable(&tmp, &path, b"hello").unwrap();
assert_eq!(std::fs::read(&path).unwrap(), b"hello");
assert!(
!tmp.exists(),
"temp file must be renamed away, not left behind"
);
write_durable(&tmp, &path, b"world!!").unwrap();
assert_eq!(std::fs::read(&path).unwrap(), b"world!!");
assert!(!tmp.exists());
}
}