From 2315a68543b1cb3b7064742d3f931bd82785cf2d Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Tue, 31 Dec 2019 13:16:04 +0100 Subject: Impl Ref for MutRefWithHasher Signed-off-by: Matthias Beyer --- lib/entry/libimagentryref/src/reference.rs | 102 +++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/lib/entry/libimagentryref/src/reference.rs b/lib/entry/libimagentryref/src/reference.rs index 0d8970f7..595962c4 100644 --- a/lib/entry/libimagentryref/src/reference.rs +++ b/lib/entry/libimagentryref/src/reference.rs @@ -272,6 +272,108 @@ pub trait MutRef { -> Result<()> where P: AsRef, Coll: AsRef; + +} + +impl<'a, H: Hasher> Ref for MutRefWithHasher<'a, H> { + + /// Check whether the underlying object is actually a ref + fn is_ref(&self) -> Result { + self.0.is::().context("Failed to check is-ref flag").map_err(Error::from) + } + + fn get_hash(&self) -> Result<&str> { + let header_path = format!("ref.hash.{}", H::NAME); + self.0 + .get_header() + .read(&header_path) + .context(format_err!("Failed to read header at '{}'", header_path)) + .map_err(Error::from)? + .ok_or_else(|| { + Error::from(EM::EntryHeaderFieldMissing("ref.hash.")) + }) + .and_then(|v| { + v.as_str().ok_or_else(|| { + Error::from(EM::EntryHeaderTypeError2("ref.hash.", "string")) + }) + }) + } + + /// Get the path of the actual file + fn get_path(&self, config: &Config) -> Result { + let basepath_name = self.0 + .get_header() + .read_string("ref.basepath")? + .ok_or_else(|| Error::from(EM::EntryHeaderFieldMissing("ref.basepath")))?; + + self.get_path_with_basepath_setting(config, basepath_name) + } + + fn get_path_with_basepath_setting(&self, config: &Config, base: B) + -> Result + where B: AsRef + { + let relpath = self.0 + .get_header() + .read_string("ref.relpath")? + .map(PathBuf::from) + .ok_or_else(|| Error::from(EM::EntryHeaderFieldMissing("ref.relpath")))?; + + get_file_path(config, base.as_ref(), relpath) + } + + /// Get the relative path, relative to the configured basepath + fn get_relative_path(&self) -> Result { + self.0 + .get_header() + .read("ref.relpath") + .context("Failed to read header at 'ref.relpath'")? + .ok_or_else(|| Error::from(EM::EntryHeaderFieldMissing("ref.relpath"))) + .and_then(|v| { + v.as_str() + .ok_or_else(|| EM::EntryHeaderTypeError2("ref.relpath", "string")) + .map_err(Error::from) + }) + .map(PathBuf::from) + } + + fn hash_valid(&self, config: &Config) -> Result { + let ref_header = self.0 + .get_header() + .read("ref") + .context("Failed to read header at 'ref'")? + .ok_or_else(|| err_msg("Header missing at 'ref'"))?; + + let basepath_name = ref_header + .read("basepath") + .context("Failed to read header at 'ref.basepath'")? + .ok_or_else(|| err_msg("Header missing at 'ref.basepath'"))? + .as_str() + .ok_or_else(|| Error::from(EM::EntryHeaderTypeError2("ref.hash.", "string")))?; + + let path = ref_header + .read("relpath") + .context("Failed to read header at 'ref.relpath'")? + .ok_or_else(|| err_msg("Header missing at 'ref.relpath'"))? + .as_str() + .map(PathBuf::from) + .ok_or_else(|| Error::from(EM::EntryHeaderTypeError2("ref.hash.", "string")))?; + + + let file_path = get_file_path(config, basepath_name, &path)?; + + ref_header + .read(H::NAME) + .context(format_err!("Failed to read header at 'ref.{}'", H::NAME))? + .ok_or_else(|| format_err!("Header missing at 'ref.{}'", H::NAME)) + .and_then(|v| { + v.as_str().ok_or_else(|| { + Error::from(EM::EntryHeaderTypeError2("ref.hash.", "string")) + }) + }) + .and_then(|hash| H::hash(file_path).map(|h| h == hash)) + } + } -- cgit v1.2.3