#![allow(dead_code)]
use std::path::PathBuf;
use std::time::UNIX_EPOCH;
#[derive(Debug, Clone)]
pub struct FileWatcher {
path: PathBuf,
}
impl FileWatcher {
#[must_use]
pub fn new(path: &str) -> Self {
Self {
path: PathBuf::from(path),
}
}
#[must_use]
pub fn from_path(path: impl Into<PathBuf>) -> Self {
Self { path: path.into() }
}
#[must_use]
pub fn poll(&self, last_modified: u64) -> Option<u64> {
let mtime = self.current_mtime()?;
if mtime > last_modified {
Some(mtime)
} else {
None
}
}
#[must_use]
pub fn current_mtime(&self) -> Option<u64> {
let meta = std::fs::metadata(&self.path).ok()?;
let modified = meta.modified().ok()?;
let duration = modified.duration_since(UNIX_EPOCH).ok()?;
Some(duration.as_secs())
}
#[must_use]
pub fn path(&self) -> &PathBuf {
&self.path
}
#[must_use]
pub fn exists(&self) -> bool {
self.path.exists()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_watcher_nonexistent_file_returns_none() {
let w = FileWatcher::new("/tmp/oximedia_watcher_nonexistent_xyz.bin");
assert!(w.poll(0).is_none());
assert!(w.current_mtime().is_none());
assert!(!w.exists());
}
#[test]
fn test_watcher_detects_existing_file() {
let dir = std::env::temp_dir();
let path = dir.join("oximedia_watcher_test.bin");
std::fs::write(&path, b"data").expect("write");
let w = FileWatcher::from_path(&path);
assert!(w.exists());
let result = w.poll(0);
assert!(result.is_some(), "should detect file with mtime > 0");
let mtime = result.expect("mtime available");
assert!(w.poll(mtime).is_none());
let _ = std::fs::remove_file(&path);
}
#[test]
fn test_watcher_path_accessor() {
let w = FileWatcher::new("/tmp/test.mp4");
assert_eq!(w.path(), &PathBuf::from("/tmp/test.mp4"));
}
#[test]
fn test_watcher_future_last_modified_returns_none() {
let dir = std::env::temp_dir();
let path = dir.join("oximedia_watcher_future_test.bin");
std::fs::write(&path, b"future").expect("write");
let w = FileWatcher::from_path(&path);
assert!(w.poll(u64::MAX).is_none());
let _ = std::fs::remove_file(&path);
}
#[test]
fn test_watcher_current_mtime_returns_reasonable_timestamp() {
let dir = std::env::temp_dir();
let path = dir.join("oximedia_watcher_mtime.bin");
std::fs::write(&path, b"ts").expect("write");
let w = FileWatcher::from_path(&path);
let mtime = w.current_mtime().expect("should have mtime");
assert!(
mtime > 946_684_800,
"mtime should be a plausible Unix timestamp"
);
let now = std::time::SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0);
assert!(mtime <= now + 2, "mtime should not be in the future");
let _ = std::fs::remove_file(&path);
}
}