summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2019-12-31 13:16:04 +0100
committerMatthias Beyer <mail@beyermatthias.de>2020-01-01 20:07:43 +0100
commit2315a68543b1cb3b7064742d3f931bd82785cf2d (patch)
tree8563f33e4d285098e8f8bf9f4635f653adb02fb0
parent6708c223abde751a1a25f8ede2ccb7713c67d049 (diff)
Impl Ref for MutRefWithHasher
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r--lib/entry/libimagentryref/src/reference.rs102
1 files changed, 102 insertions, 0 deletions
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<Path>,
Coll: AsRef<str>;
+
+}
+
+impl<'a, H: Hasher> Ref for MutRefWithHasher<'a, H> {
+
+ /// Check whether the underlying object is actually a ref
+ fn is_ref(&self) -> Result<bool> {
+ self.0.is::<IsRef>().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.<hash>"))
+ })
+ .and_then(|v| {
+ v.as_str().ok_or_else(|| {
+ Error::from(EM::EntryHeaderTypeError2("ref.hash.<hash>", "string"))
+ })
+ })
+ }
+
+ /// Get the path of the actual file
+ fn get_path(&self, config: &Config) -> Result<PathBuf> {
+ 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<B>(&self, config: &Config, base: B)
+ -> Result<PathBuf>
+ where B: AsRef<str>
+ {
+ 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<PathBuf> {
+ 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<bool> {
+ 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.<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.<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.<hash>", "string"))
+ })
+ })
+ .and_then(|hash| H::hash(file_path).map(|h| h == hash))
+ }
+
}