use std::time::{SystemTime, UNIX_EPOCH};
use crate::fs::Fs;
use crate::paths::Pather;
use crate::Result;
pub fn write_last_up_marker(fs: &dyn Fs, paths: &dyn Pather) -> Result<()> {
let ts = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0);
fs.mkdir_all(paths.data_dir())?;
fs.write_file(&paths.last_up_path(), ts.to_string().as_bytes())
}
pub fn read_last_up_marker(fs: &dyn Fs, paths: &dyn Pather) -> Option<u64> {
let path = paths.last_up_path();
if !fs.exists(&path) {
return None;
}
fs.read_to_string(&path)
.ok()
.and_then(|s| s.trim().parse::<u64>().ok())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::testing::TempEnvironment;
#[test]
fn missing_marker_reads_as_none() {
let env = TempEnvironment::builder().build();
assert_eq!(
read_last_up_marker(env.fs.as_ref(), env.paths.as_ref()),
None
);
}
#[test]
fn write_then_read_round_trip() {
let env = TempEnvironment::builder().build();
write_last_up_marker(env.fs.as_ref(), env.paths.as_ref()).unwrap();
let ts = read_last_up_marker(env.fs.as_ref(), env.paths.as_ref())
.expect("marker should exist after write");
assert!(
ts > 1_700_000_000,
"timestamp should look like a recent unix ts, got {ts}"
);
}
#[test]
fn unparseable_marker_reads_as_none() {
let env = TempEnvironment::builder().build();
env.fs.mkdir_all(env.paths.data_dir()).unwrap();
env.fs
.write_file(&env.paths.last_up_path(), b"not a number")
.unwrap();
assert_eq!(
read_last_up_marker(env.fs.as_ref(), env.paths.as_ref()),
None
);
}
}