Use error chain link functionality to remove link-conversion boilerplate
This commit is contained in:
parent
441e59753a
commit
5894c27e44
3 changed files with 36 additions and 65 deletions
|
@ -24,6 +24,14 @@ error_chain! {
|
||||||
LinkError, LinkErrorKind, ResultExt, Result;
|
LinkError, LinkErrorKind, ResultExt, Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
links {
|
||||||
|
StoreError(::libimagstore::error::StoreError, ::libimagstore::error::StoreErrorKind);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreign_links {
|
||||||
|
TomlQueryError(::toml_query::error::Error);
|
||||||
|
}
|
||||||
|
|
||||||
errors {
|
errors {
|
||||||
EntryHeaderReadError {
|
EntryHeaderReadError {
|
||||||
description("Error while reading an entry header")
|
description("Error while reading an entry header")
|
||||||
|
@ -70,21 +78,6 @@ error_chain! {
|
||||||
display("URI is not valid")
|
display("URI is not valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
StoreReadError {
|
|
||||||
description("Store read error")
|
|
||||||
display("Store read error")
|
|
||||||
}
|
|
||||||
|
|
||||||
StoreWriteError {
|
|
||||||
description("Store write error")
|
|
||||||
display("Store write error")
|
|
||||||
}
|
|
||||||
|
|
||||||
StoreIdError {
|
|
||||||
description("StoreId handling error")
|
|
||||||
display("StoreId handling error")
|
|
||||||
}
|
|
||||||
|
|
||||||
DeadLink(from: StoreId, to: StoreId) {
|
DeadLink(from: StoreId, to: StoreId) {
|
||||||
description("Dead link")
|
description("Dead link")
|
||||||
display("Dead link from: {from} to: {to}", from = from, to = to)
|
display("Dead link from: {from} to: {to}", from = from, to = to)
|
||||||
|
@ -94,11 +87,6 @@ error_chain! {
|
||||||
description("Error in link handling")
|
description("Error in link handling")
|
||||||
display("Error in link handling")
|
display("Error in link handling")
|
||||||
}
|
}
|
||||||
|
|
||||||
StoreError {
|
|
||||||
description("Error while talking to the store")
|
|
||||||
display("Error while talking to the store")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,8 +129,6 @@ pub mod iter {
|
||||||
|
|
||||||
use internal::Link;
|
use internal::Link;
|
||||||
use internal::iter::LinkIter;
|
use internal::iter::LinkIter;
|
||||||
use error::LinkErrorKind as LEK;
|
|
||||||
use error::ResultExt;
|
|
||||||
use error::Result;
|
use error::Result;
|
||||||
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -266,8 +264,8 @@ pub mod iter {
|
||||||
debug!("Retrieving entry for id: '{:?}'", id);
|
debug!("Retrieving entry for id: '{:?}'", id);
|
||||||
self.1
|
self.1
|
||||||
.retrieve(id.clone())
|
.retrieve(id.clone())
|
||||||
.chain_err(|| LEK::StoreReadError)
|
|
||||||
.map_dbg_err(|_| format!("Retrieving entry for id: '{:?}' failed", id))
|
.map_dbg_err(|_| format!("Retrieving entry for id: '{:?}' failed", id))
|
||||||
|
.map_err(From::from)
|
||||||
.and_then(|f| {
|
.and_then(|f| {
|
||||||
debug!("Store::retrieve({:?}) succeeded", id);
|
debug!("Store::retrieve({:?}) succeeded", id);
|
||||||
debug!("getting external link from file now");
|
debug!("getting external link from file now");
|
||||||
|
@ -308,7 +306,6 @@ impl ExternalLinker for Entry {
|
||||||
// /link/external/<SHA> -> load these files and get the external link from their headers,
|
// /link/external/<SHA> -> load these files and get the external link from their headers,
|
||||||
// put them into the return vector.
|
// put them into the return vector.
|
||||||
self.get_internal_links()
|
self.get_internal_links()
|
||||||
.chain_err(|| LEK::StoreReadError)
|
|
||||||
.map(|iter| {
|
.map(|iter| {
|
||||||
debug!("Getting external links");
|
debug!("Getting external links");
|
||||||
iter.only_external_links().urls(store)
|
iter.only_external_links().urls(store)
|
||||||
|
@ -330,7 +327,6 @@ impl ExternalLinker for Entry {
|
||||||
};
|
};
|
||||||
let file_id = try!(
|
let file_id = try!(
|
||||||
ModuleEntryPath::new(format!("external/{}", hash)).into_storeid()
|
ModuleEntryPath::new(format!("external/{}", hash)).into_storeid()
|
||||||
.chain_err(|| LEK::StoreWriteError)
|
|
||||||
.map_dbg_err(|_| {
|
.map_dbg_err(|_| {
|
||||||
format!("Failed to build StoreId for this hash '{:?}'", hash)
|
format!("Failed to build StoreId for this hash '{:?}'", hash)
|
||||||
})
|
})
|
||||||
|
@ -344,7 +340,6 @@ impl ExternalLinker for Entry {
|
||||||
// exist
|
// exist
|
||||||
let mut file = try!(store
|
let mut file = try!(store
|
||||||
.retrieve(file_id.clone())
|
.retrieve(file_id.clone())
|
||||||
.chain_err(|| LEK::StoreWriteError)
|
|
||||||
.map_dbg_err(|_| {
|
.map_dbg_err(|_| {
|
||||||
format!("Failed to create or retrieve an file for this link '{:?}'", link)
|
format!("Failed to create or retrieve an file for this link '{:?}'", link)
|
||||||
}));
|
}));
|
||||||
|
@ -353,15 +348,14 @@ impl ExternalLinker for Entry {
|
||||||
{
|
{
|
||||||
let hdr = file.deref_mut().get_header_mut();
|
let hdr = file.deref_mut().get_header_mut();
|
||||||
|
|
||||||
let mut table = match hdr.read("links.external.content") {
|
let mut table = match try!(hdr.read("links.external.content")) {
|
||||||
Ok(Some(&Value::Table(ref table))) => table.clone(),
|
Some(&Value::Table(ref table)) => table.clone(),
|
||||||
Ok(Some(_)) => {
|
Some(_) => {
|
||||||
warn!("There is a value at 'links.external.content' which is not a table.");
|
warn!("There is a value at 'links.external.content' which is not a table.");
|
||||||
warn!("Going to override this value");
|
warn!("Going to override this value");
|
||||||
BTreeMap::new()
|
BTreeMap::new()
|
||||||
},
|
},
|
||||||
Ok(None) => BTreeMap::new(),
|
None => BTreeMap::new(),
|
||||||
Err(e) => return Err(e).chain_err(|| LEK::StoreWriteError),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let v = Value::String(link.into_string());
|
let v = Value::String(link.into_string());
|
||||||
|
@ -369,18 +363,13 @@ impl ExternalLinker for Entry {
|
||||||
debug!("setting URL = '{:?}", v);
|
debug!("setting URL = '{:?}", v);
|
||||||
table.insert(String::from("url"), v);
|
table.insert(String::from("url"), v);
|
||||||
|
|
||||||
if let Err(e) = hdr.insert("links.external.content", Value::Table(table)) {
|
let _ = try!(hdr.insert("links.external.content", Value::Table(table)));
|
||||||
return Err(e).chain_err(|| LEK::StoreWriteError);
|
debug!("Setting URL worked");
|
||||||
} else {
|
|
||||||
debug!("Setting URL worked");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// then add an internal link to the new file or return an error if this fails
|
// then add an internal link to the new file or return an error if this fails
|
||||||
if let Err(e) = self.add_internal_link(file.deref_mut()) {
|
let _ = try!(self.add_internal_link(file.deref_mut()));
|
||||||
debug!("Error adding internal link");
|
debug!("Error adding internal link");
|
||||||
return Err(e).chain_err(|| LEK::StoreWriteError);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
debug!("Ready iterating");
|
debug!("Ready iterating");
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -51,7 +51,7 @@ impl Link {
|
||||||
Link::Id { ref link } => link.exists(),
|
Link::Id { ref link } => link.exists(),
|
||||||
Link::Annotated { ref link, .. } => link.exists(),
|
Link::Annotated { ref link, .. } => link.exists(),
|
||||||
}
|
}
|
||||||
.chain_err(|| LEK::StoreIdError)
|
.map_err(From::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_str(&self) -> Result<String> {
|
pub fn to_str(&self) -> Result<String> {
|
||||||
|
@ -59,7 +59,7 @@ impl Link {
|
||||||
Link::Id { ref link } => link.to_str(),
|
Link::Id { ref link } => link.to_str(),
|
||||||
Link::Annotated { ref link, .. } => link.to_str(),
|
Link::Annotated { ref link, .. } => link.to_str(),
|
||||||
}
|
}
|
||||||
.chain_err(|| LEK::StoreReadError)
|
.map_err(From::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -288,10 +288,10 @@ pub mod iter {
|
||||||
type Item = Result<FileLockEntry<'a>>;
|
type Item = Result<FileLockEntry<'a>>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
self.0.next().and_then(|id| match self.1.get(id).chain_err(|| LEK::StoreReadError) {
|
self.0.next().and_then(|id| match self.1.get(id) {
|
||||||
Ok(None) => None,
|
Ok(None) => None,
|
||||||
Ok(Some(x)) => Some(Ok(x)),
|
Ok(Some(x)) => Some(Ok(x)),
|
||||||
Err(e) => Some(Err(e)),
|
Err(e) => Some(Err(e).map_err(From::from)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,8 +318,7 @@ pub mod iter {
|
||||||
loop {
|
loop {
|
||||||
match self.0.next() {
|
match self.0.next() {
|
||||||
Some(Ok(fle)) => {
|
Some(Ok(fle)) => {
|
||||||
let links = match fle.get_internal_links().chain_err(|| LEK::StoreReadError)
|
let links = match fle.get_internal_links() {
|
||||||
{
|
|
||||||
Err(e) => return Some(Err(e)),
|
Err(e) => return Some(Err(e)),
|
||||||
Ok(links) => links.collect::<Vec<_>>(),
|
Ok(links) => links.collect::<Vec<_>>(),
|
||||||
};
|
};
|
||||||
|
@ -358,19 +357,14 @@ pub mod iter {
|
||||||
loop {
|
loop {
|
||||||
match self.0.next() {
|
match self.0.next() {
|
||||||
Some(Ok(fle)) => {
|
Some(Ok(fle)) => {
|
||||||
let links = match fle.get_internal_links().chain_err(|| LEK::StoreReadError)
|
let links = match fle.get_internal_links() {
|
||||||
{
|
|
||||||
Err(e) => return Some(Err(e)),
|
Err(e) => return Some(Err(e)),
|
||||||
Ok(links) => links,
|
Ok(links) => links,
|
||||||
};
|
};
|
||||||
if links.count() == 0 {
|
if links.count() == 0 {
|
||||||
match self.0
|
match self.0.store().delete(fle.get_location().clone()) {
|
||||||
.store()
|
|
||||||
.delete(fle.get_location().clone())
|
|
||||||
.chain_err(|| LEK::StoreWriteError)
|
|
||||||
{
|
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(e) => return Some(Err(e)),
|
Err(e) => return Some(Err(e).map_err(From::from)),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Some(Ok(fle));
|
return Some(Ok(fle));
|
||||||
|
@ -562,8 +556,8 @@ fn process_rw_result(links: Result<Option<Value>>) -> Result<LinkIter> {
|
||||||
debug!("Matching the link: {:?}", link);
|
debug!("Matching the link: {:?}", link);
|
||||||
match link {
|
match link {
|
||||||
Value::String(s) => StoreId::new_baseless(PathBuf::from(s))
|
Value::String(s) => StoreId::new_baseless(PathBuf::from(s))
|
||||||
.chain_err(|| LEK::StoreIdError)
|
|
||||||
.map(|s| Link::Id { link: s })
|
.map(|s| Link::Id { link: s })
|
||||||
|
.map_err(From::from)
|
||||||
,
|
,
|
||||||
Value::Table(mut tab) => {
|
Value::Table(mut tab) => {
|
||||||
debug!("Destructuring table");
|
debug!("Destructuring table");
|
||||||
|
@ -582,7 +576,7 @@ fn process_rw_result(links: Result<Option<Value>>) -> Result<LinkIter> {
|
||||||
match (link, anno) {
|
match (link, anno) {
|
||||||
(Value::String(link), Value::String(anno)) => {
|
(Value::String(link), Value::String(anno)) => {
|
||||||
StoreId::new_baseless(PathBuf::from(link))
|
StoreId::new_baseless(PathBuf::from(link))
|
||||||
.chain_err(|| LEK::StoreIdError)
|
.map_err(From::from)
|
||||||
.map(|link| {
|
.map(|link| {
|
||||||
Link::Annotated {
|
Link::Annotated {
|
||||||
link: link,
|
link: link,
|
||||||
|
@ -642,24 +636,24 @@ pub mod store_check {
|
||||||
/// The lambda returns an error if something fails
|
/// The lambda returns an error if something fails
|
||||||
let aggregate_link_network = |store: &Store| -> Result<HashMap<StoreId, Linking>> {
|
let aggregate_link_network = |store: &Store| -> Result<HashMap<StoreId, Linking>> {
|
||||||
let iter = store
|
let iter = store
|
||||||
.entries()
|
.entries()?
|
||||||
.chain_err(|| LEK::StoreReadError)?
|
|
||||||
.into_get_iter(store);
|
.into_get_iter(store);
|
||||||
|
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
for element in iter {
|
for element in iter {
|
||||||
debug!("Checking element = {:?}", element);
|
debug!("Checking element = {:?}", element);
|
||||||
let entry = match element {
|
let entry = match try!(element) {
|
||||||
Ok(Some(e)) => e,
|
Some(e) => e,
|
||||||
Ok(None) => return Err(LE::from_kind(LEK::StoreIdError)),
|
None => {
|
||||||
Err(e) => return Err(e).chain_err(|| LE::from_kind(LEK::StoreReadError)),
|
let e = String::from("TODO: Not yet handled");
|
||||||
|
return Err(e).map_err(From::from);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("Checking entry = {:?}", entry.get_location());
|
debug!("Checking entry = {:?}", entry.get_location());
|
||||||
|
|
||||||
let internal_links = entry
|
let internal_links = entry
|
||||||
.get_internal_links()
|
.get_internal_links()?
|
||||||
.chain_err(|| LEK::StoreError)?
|
|
||||||
.into_getter(store); // get the FLEs from the Store
|
.into_getter(store); // get the FLEs from the Store
|
||||||
|
|
||||||
let mut linking = Linking::default();
|
let mut linking = Linking::default();
|
||||||
|
@ -686,7 +680,7 @@ pub mod store_check {
|
||||||
if is_match!(self.get(id.clone()), Ok(Some(_))) {
|
if is_match!(self.get(id.clone()), Ok(Some(_))) {
|
||||||
debug!("Exists in store: {:?}", id);
|
debug!("Exists in store: {:?}", id);
|
||||||
|
|
||||||
if !try!(id.exists().chain_err(|| LEK::StoreReadError)) {
|
if !try!(id.exists()) {
|
||||||
warn!("Does exist in store but not on FS: {:?}", id);
|
warn!("Does exist in store but not on FS: {:?}", id);
|
||||||
Err(LE::from_kind(LEK::LinkTargetDoesNotExist))
|
Err(LE::from_kind(LEK::LinkTargetDoesNotExist))
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue