diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 28 |
1 files changed, 20 insertions, 8 deletions
@@ -42,6 +42,14 @@ const BUF_SIZE: usize = 1024 * 1024; /// An entry in a file manifest. #[derive(Serialize, Debug)] pub struct ManifestEntry { + #[serde(skip)] + is_regular: bool, + + // Store the original name in a hidden field, for compute_checksum. + #[serde(skip)] + filename: PathBuf, + + // We store pathname as a string so that we can handle non-UTF8 names. path: String, #[serde(with = "mode")] mode: u32, @@ -60,29 +68,33 @@ impl ManifestEntry { /// caller. This function doesn't query the system for it. /// /// The structure can be serialized using serde. - pub fn new(path: &Path) -> std::io::Result<Self> { + pub async fn new(path: &Path) -> std::io::Result<Self> { let m = symlink_metadata(path)?; - let hash = if m.is_file() { - Some(file_checksum(path)?) - } else { - None - }; let target = if m.file_type().is_symlink() { Some(read_link(path)?) } else { None }; Ok(Self { + is_regular: m.is_file(), + filename: path.to_path_buf(), path: path.to_string_lossy().into_owned(), 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()) }, - sha256: hash, + sha256: None, target, }) } + + pub fn compute_checksum(&mut self) -> std::io::Result<()> { + if self.is_regular { + self.sha256 = Some(file_checksum(&self.filename)?); + } + Ok(()) + } } fn file_checksum(path: &Path) -> std::io::Result<String> { @@ -90,8 +102,8 @@ fn file_checksum(path: &Path) -> std::io::Result<String> { let file = File::open(path)?; let mut reader = BufReader::new(file); - let mut buf = vec![0; BUF_SIZE]; loop { + let mut buf = vec![0; BUF_SIZE]; let n = reader.read(&mut buf)?; if n == 0 { break; |