Index: Cargo.toml ================================================================== --- Cargo.toml +++ Cargo.toml @@ -1,8 +1,8 @@ [package] name = "orphanage" -version = "0.1.3" +version = "0.1.4" edition = "2021" license = "0BSD" # https://crates.io/category_slugs categories = [ "network-programming" ] keywords = [ "sqlite", "fs", "path" ] Index: src/fs.rs ================================================================== --- src/fs.rs +++ src/fs.rs @@ -1,7 +1,8 @@ use std::{ fs, + io::ErrorKind, path::{Path, PathBuf} }; use crate::err::Error; @@ -63,6 +64,59 @@ P: AsRef { Ok(pth.as_ref().canonicalize()?) } + +/// Call a closure if `outfile` is outdated (according to the rules of +/// [`outdated()`] with regards to `infile`. +/// +/// Returns `Ok(true)` if the closure was called. +/// +/// # Errors +/// Errors mirror the behavior of [`outdated()`]'s errors. +pub fn run_if_outdated( + srcfile: impl AsRef, + dstfile: impl AsRef, + f: F +) -> Result +where + F: FnOnce(&Path, &Path) +{ + if outdated(&srcfile, &dstfile)? { + f(srcfile.as_ref(), dstfile.as_ref()); + Ok(true) + } else { + Ok(false) + } +} + +/// Returns `true` if `infile` is newer than `outfile` (or if `outfile` doesn't +/// exist). Returns `false` otherwise. +/// +/// # Errors +/// Returns [`std::io::Error`] if: +/// - `infile`'s metadata could not be read. +/// - `outfile`'s metadata could not be read and it is other than +/// `ErrorKind::NotFound`. +/// - Either `infile`' or `outfile`'s mtime could not be extracted. +pub fn outdated( + infile: impl AsRef, + outfile: impl AsRef +) -> Result { + let in_md = fs::metadata(infile.as_ref())?; + let out_md = match fs::metadata(outfile.as_ref()) { + Ok(md) => md, + Err(err) if err.kind() == ErrorKind::NotFound => { + // If the target file could not be found then treat target as outdated + return Ok(true); + } + Err(e) => Err(e)? + }; + + let in_mtime = in_md.modified()?; + let out_mtime = out_md.modified()?; + + Ok(in_mtime > out_mtime) +} + // vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 : Index: www/changelog.md ================================================================== --- www/changelog.md +++ www/changelog.md @@ -1,17 +1,30 @@ # Change Log ## [Unreleased] -[Details](/vdiff?from=orphanage-0.1.3&to=trunk) +[Details](/vdiff?from=orphanage-0.1.4&to=trunk) ### Added ### Changed ### Removed +--- + +## [0.1.4] - 2024-11-22 + +[Details](/vdiff?from=orphanage-0.1.3&to=orphanage-0.1.4) + +### Added + +- `fs::outdated()` can be used to detect of a file is "outdated" with regards + to another. +- `fs::run_if_outdated()` can be used to run a closure if a file is "outdated" + with regards to another. + --- ## [0.1.3] - 2024-11-07 [Details](/vdiff?from=orphanage-0.1.2&to=orphanage-0.1.3)