Refactor: Remove notion of "external link"s

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
Matthias Beyer 2019-06-23 13:11:23 +02:00
parent 59ddb70345
commit cdc90f7be7
4 changed files with 54 additions and 72 deletions

View File

@ -37,7 +37,7 @@ use libimagutil::debug_result::DebugResult;
use failure::Fallible as Result;
use url::Url;
/// Helper for building `OnlyExternalIter` and `NoExternalIter`
/// Helper for building `OnlyUrlIter` and `NoUrlIter`
///
/// The boolean value defines, how to interpret the `is_external_link_storeid()` return value
/// (here as "pred"):
@ -55,9 +55,9 @@ use url::Url;
/// false... and so on.
///
/// As we can see, the operator between these two operants is `!(a ^ b)`.
pub struct ExternalFilterIter(LinkIter, bool);
pub struct UrlFilterIter(LinkIter, bool);
impl Iterator for ExternalFilterIter {
impl Iterator for UrlFilterIter {
type Item = Link;
fn next(&mut self) -> Option<Self::Item> {
@ -78,24 +78,24 @@ impl Iterator for ExternalFilterIter {
///
/// # See also
///
/// Also see `OnlyExternalIter` and `NoExternalIter` and the helper traits/functions
/// `OnlyInteralLinks`/`only_links()` and `OnlyExternalLinks`/`only_urls()`.
pub trait SelectExternal {
fn select_urls(self, b: bool) -> ExternalFilterIter;
/// Also see `OnlyUrlIter` and `NoUrlIter` and the helper traits/functions
/// `OnlyInteralLinks`/`only_links()` and `OnlyUrlLinks`/`only_urls()`.
pub trait SelectUrl {
fn select_urls(self, b: bool) -> UrlFilterIter;
}
impl SelectExternal for LinkIter {
fn select_urls(self, b: bool) -> ExternalFilterIter {
ExternalFilterIter(self, b)
impl SelectUrl for LinkIter {
fn select_urls(self, b: bool) -> UrlFilterIter {
UrlFilterIter(self, b)
}
}
pub struct OnlyExternalIter(ExternalFilterIter);
pub struct OnlyUrlIter(UrlFilterIter);
impl OnlyExternalIter {
pub fn new(li: LinkIter) -> OnlyExternalIter {
OnlyExternalIter(ExternalFilterIter(li, true))
impl OnlyUrlIter {
pub fn new(li: LinkIter) -> OnlyUrlIter {
OnlyUrlIter(UrlFilterIter(li, true))
}
pub fn urls<'a>(self, store: &'a Store) -> UrlIter<'a> {
@ -103,7 +103,7 @@ impl OnlyExternalIter {
}
}
impl Iterator for OnlyExternalIter {
impl Iterator for OnlyUrlIter {
type Item = Link;
fn next(&mut self) -> Option<Self::Item> {
@ -111,15 +111,15 @@ impl Iterator for OnlyExternalIter {
}
}
pub struct NoExternalIter(ExternalFilterIter);
pub struct NoUrlIter(UrlFilterIter);
impl NoExternalIter {
pub fn new(li: LinkIter) -> NoExternalIter {
NoExternalIter(ExternalFilterIter(li, false))
impl NoUrlIter {
pub fn new(li: LinkIter) -> NoUrlIter {
NoUrlIter(UrlFilterIter(li, false))
}
}
impl Iterator for NoExternalIter {
impl Iterator for NoUrlIter {
type Item = Link;
fn next(&mut self) -> Option<Self::Item> {
@ -127,35 +127,35 @@ impl Iterator for NoExternalIter {
}
}
pub trait OnlyExternalLinks : Sized {
fn only_urls(self) -> OnlyExternalIter ;
pub trait OnlyUrlLinks : Sized {
fn only_urls(self) -> OnlyUrlIter ;
fn no_links(self) -> OnlyExternalIter {
fn no_links(self) -> OnlyUrlIter {
self.only_urls()
}
}
impl OnlyExternalLinks for LinkIter {
fn only_urls(self) -> OnlyExternalIter {
OnlyExternalIter::new(self)
impl OnlyUrlLinks for LinkIter {
fn only_urls(self) -> OnlyUrlIter {
OnlyUrlIter::new(self)
}
}
pub trait OnlyInternalLinks : Sized {
fn only_links(self) -> NoExternalIter;
fn only_links(self) -> NoUrlIter;
fn no_urls(self) -> NoExternalIter {
fn no_urls(self) -> NoUrlIter {
self.only_links()
}
}
impl OnlyInternalLinks for LinkIter {
fn only_links(self) -> NoExternalIter {
NoExternalIter::new(self)
fn only_links(self) -> NoUrlIter {
NoUrlIter::new(self)
}
}
pub struct UrlIter<'a>(OnlyExternalIter, &'a Store);
pub struct UrlIter<'a>(OnlyUrlIter, &'a Store);
impl<'a> Iterator for UrlIter<'a> {
type Item = Result<Url>;
@ -174,7 +174,7 @@ impl<'a> Iterator for UrlIter<'a> {
.map_err(From::from)
.and_then(|f| {
debug!("Store::retrieve({:?}) succeeded", id);
debug!("getting external link from file now");
debug!("getting uri link from file now");
f.get_link_uri_from_filelockentry()
.map_dbg_str("Error happened while getting link URI from FLE")
.map_dbg_err(|e| format!("URL -> Err = {:?}", e))

View File

@ -40,8 +40,8 @@ impl Link for Entry {
fn get_link_uri_from_filelockentry(&self) -> Result<Option<Url>> {
self.get_header()
.read_string("links.external.content.url")
.context(format_err!("Error reading header 'links.external.content.url' from '{}'", self.get_location()))
.read_string("url.uri")
.context(format_err!("Error reading header 'url.uri' from '{}'", self.get_location()))
.context(EM::EntryHeaderReadError)
.map_err(Error::from)
.and_then(|opt| match opt {
@ -61,7 +61,7 @@ impl Link for Entry {
}
fn get_url(&self) -> Result<Option<Url>> {
match self.get_header().read_string("links.external.url")? {
match self.get_header().read_string("url.uri")? {
None => Ok(None),
Some(ref s) => Url::parse(&s[..])
.context(format_err!("Failed to parse URL: '{}'", s))

View File

@ -38,56 +38,48 @@ use crate::iter::UrlIter;
pub trait UrlLinker : Linkable {
/// Get the external links from the implementor object
/// Get the urls from the implementor object
fn get_urls<'a>(&self, store: &'a Store) -> Result<UrlIter<'a>>;
/// Set the external links for the implementor object
/// Set the urls for the implementor object
fn set_urls(&mut self, store: &Store, links: Vec<Url>) -> Result<Vec<StoreId>>;
/// Add an external link to the implementor object
/// Add an url to the implementor object
fn add_url(&mut self, store: &Store, link: Url) -> Result<Vec<StoreId>>;
/// Remove an external link from the implementor object
/// Remove an url from the implementor object
fn remove_url(&mut self, store: &Store, link: Url) -> Result<Vec<StoreId>>;
}
/// Implement `ExternalLinker` for `Entry`, hiding the fact that there is no such thing as an external
/// link in an entry, but internal links to other entries which serve as external links, as one
/// entry in the store can only have one external link.
impl UrlLinker for Entry {
/// Get the external links from the implementor object
fn get_urls<'a>(&self, store: &'a Store) -> Result<UrlIter<'a>> {
use crate::iter::OnlyExternalLinks;
use crate::iter::OnlyUrlLinks;
// Iterate through all internal links and filter for FileLockEntries which live in
// /link/external/<SHA> -> load these files and get the external link from their headers,
// /links/<SHA> -> load these files and get the url from their headers,
// put them into the return vector.
self.links()
.map(|iter| {
debug!("Getting external links");
debug!("Getting urls");
iter.only_urls().urls(store)
})
}
/// Set the external links for the implementor object
/// Set the url links for the implementor object
///
/// # Return Value
///
/// Returns the StoreIds which were newly created for the new external links, if there are more
/// external links than before.
/// If there are less external links than before, an empty vec![] is returned.
/// Returns the StoreIds which were newly created for the new urls, if there are more
/// urls than before.
/// If there are less urls than before, an empty vec![] is returned.
///
fn set_urls(&mut self, store: &Store, links: Vec<Url>) -> Result<Vec<StoreId>> {
// Take all the links, generate a SHA sum out of each one, filter out the already existing
// store entries and store the other URIs in the header of one FileLockEntry each, in
// the path /link/external/<SHA of the URL>
debug!("Iterating {} links = {:?}", links.len(), links);
links.into_iter().map(|link| {
let hash = hex::encode(Sha1::digest(&link.as_str().as_bytes()));
let file_id = crate::module_path::new_id(format!("external/{}", hash))
let file_id = crate::module_path::new_id(format!("links/{}", hash))
.map_dbg_err(|_| {
format!("Failed to build StoreId for this hash '{:?}'", hash)
})?;
@ -142,18 +134,13 @@ impl UrlLinker for Entry {
.collect()
}
/// Add an external link to the implementor object
/// Add an url to the implementor object
///
/// # Return Value
///
/// (See ExternalLinker::set_urls())
///
/// Returns the StoreIds which were newly created for the new external links, if there are more
/// external links than before.
/// If there are less external links than before, an empty vec![] is returned.
/// (See UrlLinker::set_urls())
///
fn add_url(&mut self, store: &Store, link: Url) -> Result<Vec<StoreId>> {
// get external links, add this one, save them
debug!("Getting links");
self.get_urls(store)
.and_then(|links| {
@ -167,18 +154,13 @@ impl UrlLinker for Entry {
})
}
/// Remove an external link from the implementor object
/// Remove an url from the implementor object
///
/// # Return Value
///
/// (See ExternalLinker::set_urls())
///
/// Returns the StoreIds which were newly created for the new external links, if there are more
/// external links than before.
/// If there are less external links than before, an empty vec![] is returned.
/// (See UrlLinker::set_urls())
///
fn remove_url(&mut self, store: &Store, link: Url) -> Result<Vec<StoreId>> {
// get external links, remove this one, save them
self.get_urls(store)
.and_then(|links| {
debug!("Removing link = '{:?}'", link);

View File

@ -21,8 +21,8 @@ use std::fmt::Debug;
use libimagstore::storeid::StoreId;
/// Check whether the StoreId starts with `/link/external/`
/// Check whether the StoreId starts with `/url/`
pub fn is_external_link_storeid<A: AsRef<StoreId> + Debug>(id: A) -> bool {
debug!("Checking whether this is a 'url/external/': '{:?}'", id);
id.as_ref().is_in_collection(&["url", "external"])
debug!("Checking whether this is a 'url/': '{:?}'", id);
id.as_ref().is_in_collection(&["url"])
}