summaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs28
1 files changed, 20 insertions, 8 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 3c90156..7075477 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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;