From 4b98b168e58383755952cf7fa59b146a91932e89 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 23 Jun 2016 23:00:34 +0200 Subject: [PATCH] Impl Ref::exists() --- libimagref/src/reference.rs | 51 ++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/libimagref/src/reference.rs b/libimagref/src/reference.rs index fb0d34eb..aadec161 100644 --- a/libimagref/src/reference.rs +++ b/libimagref/src/reference.rs @@ -268,7 +268,56 @@ impl<'a> Ref<'a> { /// Check whether there is a reference to the file at `pb` pub fn exists(store: &Store, pb: PathBuf) -> Result { - unimplemented!() + pb.canonicalize() + .map_err(Box::new) + .map_err(|e| REK::PathCanonicalizationError.into_error_with_cause(e)) + .and_then(|can| { + Ref::hash_path(&can) + .map_err(Box::new) + .map_err(|e| REK::PathHashingError.into_error_with_cause(e)) + }) + .and_then(|hash| { + store.retrieve_for_module("ref").map(|iter| (hash, iter)) + .map_err(Box::new) + .map_err(|e| REK::StoreReadError.into_error_with_cause(e)) + }) + .and_then(|(hash, possible_refs)| { + // This is kind of a manual Iterator::filter() call what we do here, but with the + // actual ::filter method we cannot return the error in a nice way, so we do it + // manually here. If you can come up with a better version of this, feel free to + // take this note as a todo. + for r in possible_refs { + let contains_hash = match r.to_str() { + None => { // couldn't parse StoreId -> PathBuf -> &str + // TODO: How to report this? + return Err(REK::TypeConversionError.into_error()); + }, + Some(s) => s.contains(&hash[..]), + }; + + if !contains_hash { + continue; + } + + match store.get(r) { + Ok(Some(fle)) => { + if Ref::read_reference(&fle).map(|path| path == pb).unwrap_or(false) { + return Ok(true) + } + }, + + Ok(None) => { // Something weird just happened + return Err(REK::StoreReadError.into_error()); + }, + + Err(e) => { + return Err(REK::StoreReadError.into_error_with_cause(Box::new(e))); + }, + } + } + + Ok(false) + }) } /// Re-find a referenced file