//! Noticing that something else changed a file: cumulus remembers each //! document file's [`Stamp`] when it reads or writes it, and looks again //! every second. A different stamp means another program (an editor, a //! sync tool, another cumulus) wrote the file, and cumulus reloads it. //! Looking costs one quick question to the file system per document, so //! there's no need for a file-watching library. use std::fs; use std::io; use std::path::Path; use std::time::SystemTime; /// When a file was last written, and how long it is. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Stamp { modified: SystemTime, len: u64, } impl Stamp { /// The stamp of the file at `path`, or `None` when there's no file there. pub fn of(path: &Path) -> io::Result> { match fs::metadata(path) { Ok(metadata) => Ok(Some(Stamp { modified: metadata.modified()?, len: metadata.len() })), Err(error) if error.kind() == io::ErrorKind::NotFound => Ok(None), Err(error) => Err(error), } } } #[cfg(test)] mod tests { use super::*; use crate::storage::test_support::TempDir; #[test] fn a_write_changes_the_stamp() { let folder = TempDir::new(); let path = folder.path().join("garden.cum"); assert_eq!(Stamp::of(&path).unwrap(), None); fs::write(&path, "one").unwrap(); let first = Stamp::of(&path).unwrap(); assert_eq!(Stamp::of(&path).unwrap(), first, "nothing changed"); fs::write(&path, "three").unwrap(); assert_ne!(Stamp::of(&path).unwrap(), first); } }