diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 83 |
1 files changed, 83 insertions, 0 deletions
@@ -1 +1,84 @@ +//! File manifests. +//! +//! This crate defines the [`ManifestEntry`] struct to represent an +//! entry in a file manifest. The entry contains data about each file. +//! A manifest can be produced of some data, and later, a new manifest +//! can be produced and compared with the original. If the manifests +//! have changed, the data has changed. If they haven't changed, the +//! data has probably not changed. +//! +//! Such manifests can be used, for example, to verify that data that +//! has been restored from a backup is the same as what was backed up. +//! +//! This crate uses Linux metadata of files. +//! +//! ~~~ +//! let m = std::fs::metadata(".").unwrap(); +//! let e = summain::ManifestEntry(m); +//! println!("{}", serde_yaml::to_string(e).unwrap()); +//! ~~~ +//! +//! The output is something like: +//! +//! ~~~yaml +//! path: "." +//! atime: 1606565868 +//! atime_nsec: 824368155 +//! mode: drwxrwxr-x +//! mtime: 1606565867 +//! mtime_nsec: 500355545 +//! nlink: 6 +//! size: ~ +//! ~~~ +use serde::Serialize; +use std::fs::Metadata; +use std::os::linux::fs::MetadataExt; +use std::path::{Path, PathBuf}; + +/// An entry in a file manifest. +#[derive(Serialize, Debug)] +pub struct ManifestEntry { + path: PathBuf, + atime: i64, + atime_nsec: i64, + #[serde(with = "mode")] + mode: u32, + mtime: i64, + mtime_nsec: i64, + nlink: u64, + size: Option<u64>, +} + +impl ManifestEntry { + /// Create a new manifest entry. + /// + /// The pathname of the file and the metadata are passed in by the + /// caller. This function doesn't query the system for it. + /// + /// The structure can be serialized using serde. + pub fn new(path: &Path, m: Metadata) -> Self { + Self { + path: path.to_path_buf(), + atime: m.st_atime(), + atime_nsec: m.st_atime_nsec(), + mode: m.st_mode(), + mtime: m.st_mtime(), + mtime_nsec: m.st_mtime_nsec(), + nlink: m.st_nlink(), + size: if m.is_dir() { None } else { Some(m.st_size()) }, + } + } +} + +mod mode { + use serde::{self, Serializer}; + + pub fn serialize<S>(mode: &u32, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let s = unix_mode::to_string(*mode); + serializer.serialize_str(&s) + } +} |