Change libimag{bookmark, entrylink} external linking
...to report newly created entries, so that we can re-use these new entries in the library-using code (for example for ID reporting). Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
parent
1e6d58bf4c
commit
d1f087eb57
2 changed files with 48 additions and 15 deletions
|
@ -34,6 +34,7 @@ use libimagstore::store::Store;
|
||||||
use libimagstore::store::Entry;
|
use libimagstore::store::Entry;
|
||||||
use libimagstore::store::FileLockEntry;
|
use libimagstore::store::FileLockEntry;
|
||||||
use libimagstore::storeid::IntoStoreId;
|
use libimagstore::storeid::IntoStoreId;
|
||||||
|
use libimagstore::storeid::StoreId;
|
||||||
use libimagentrylink::external::ExternalLinker;
|
use libimagentrylink::external::ExternalLinker;
|
||||||
use libimagentrylink::external::iter::UrlIter;
|
use libimagentrylink::external::iter::UrlIter;
|
||||||
use libimagentrylink::internal::InternalLinker;
|
use libimagentrylink::internal::InternalLinker;
|
||||||
|
@ -76,10 +77,10 @@ impl<'a> BookmarkCollectionStore<'a> for Store {
|
||||||
|
|
||||||
pub trait BookmarkCollection : Sized + InternalLinker + ExternalLinker {
|
pub trait BookmarkCollection : Sized + InternalLinker + ExternalLinker {
|
||||||
fn links<'a>(&self, store: &'a Store) -> Result<UrlIter<'a>>;
|
fn links<'a>(&self, store: &'a Store) -> Result<UrlIter<'a>>;
|
||||||
fn link_entries(&self) -> Result<Vec<StoreLink>>;
|
fn link_entries(&self) -> Result<Vec<StoreLink>>;
|
||||||
fn add_link(&mut self, store: &Store, l: Link) -> Result<()>;
|
fn add_link(&mut self, store: &Store, l: Link) -> Result<Vec<StoreId>>;
|
||||||
fn get_links_matching<'a>(&self, store: &'a Store, r: Regex) -> Result<LinksMatchingRegexIter<'a>>;
|
fn get_links_matching<'a>(&self, store: &'a Store, r: Regex) -> Result<LinksMatchingRegexIter<'a>>;
|
||||||
fn remove_link(&mut self, store: &Store, l: Link) -> Result<()>;
|
fn remove_link(&mut self, store: &Store, l: Link) -> Result<Vec<StoreId>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BookmarkCollection for Entry {
|
impl BookmarkCollection for Entry {
|
||||||
|
@ -93,7 +94,7 @@ impl BookmarkCollection for Entry {
|
||||||
self.get_internal_links().map(|v| v.filter(|id| is_external_link_storeid(id)).collect())
|
self.get_internal_links().map(|v| v.filter(|id| is_external_link_storeid(id)).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_link(&mut self, store: &Store, l: Link) -> Result<()> {
|
fn add_link(&mut self, store: &Store, l: Link) -> Result<Vec<StoreId>> {
|
||||||
use link::IntoUrl;
|
use link::IntoUrl;
|
||||||
l.into_url().and_then(|url| self.add_external_link(store, url))
|
l.into_url().and_then(|url| self.add_external_link(store, url))
|
||||||
}
|
}
|
||||||
|
@ -103,7 +104,7 @@ impl BookmarkCollection for Entry {
|
||||||
self.get_external_links(store).map(|iter| iter.matching_regex(r))
|
self.get_external_links(store).map(|iter| iter.matching_regex(r))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_link(&mut self, store: &Store, l: Link) -> Result<()> {
|
fn remove_link(&mut self, store: &Store, l: Link) -> Result<Vec<StoreId>> {
|
||||||
use link::IntoUrl;
|
use link::IntoUrl;
|
||||||
l.into_url().and_then(|url| self.remove_external_link(store, url))
|
l.into_url().and_then(|url| self.remove_external_link(store, url))
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,13 +108,13 @@ pub trait ExternalLinker : InternalLinker {
|
||||||
fn get_external_links<'a>(&self, store: &'a Store) -> Result<UrlIter<'a>>;
|
fn get_external_links<'a>(&self, store: &'a Store) -> Result<UrlIter<'a>>;
|
||||||
|
|
||||||
/// Set the external links for the implementor object
|
/// Set the external links for the implementor object
|
||||||
fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()>;
|
fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<Vec<StoreId>>;
|
||||||
|
|
||||||
/// Add an external link to the implementor object
|
/// Add an external link to the implementor object
|
||||||
fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()>;
|
fn add_external_link(&mut self, store: &Store, link: Url) -> Result<Vec<StoreId>>;
|
||||||
|
|
||||||
/// Remove an external link from the implementor object
|
/// Remove an external link from the implementor object
|
||||||
fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()>;
|
fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<Vec<StoreId>>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,13 +322,20 @@ impl ExternalLinker for Entry {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the external links for the implementor object
|
/// Set the external links for the implementor object
|
||||||
fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()> {
|
///
|
||||||
|
/// # 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.
|
||||||
|
///
|
||||||
|
fn set_external_links(&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
|
// 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
|
// store entries and store the other URIs in the header of one FileLockEntry each, in
|
||||||
// the path /link/external/<SHA of the URL>
|
// the path /link/external/<SHA of the URL>
|
||||||
|
|
||||||
debug!("Iterating {} links = {:?}", links.len(), links);
|
debug!("Iterating {} links = {:?}", links.len(), links);
|
||||||
for link in links { // for all links
|
links.into_iter().map(|link| {
|
||||||
let hash = hex::encode(Sha1::digest(&link.as_str().as_bytes()));
|
let hash = hex::encode(Sha1::digest(&link.as_str().as_bytes()));
|
||||||
let file_id =
|
let file_id =
|
||||||
ModuleEntryPath::new(format!("external/{}", hash)).into_storeid()
|
ModuleEntryPath::new(format!("external/{}", hash)).into_storeid()
|
||||||
|
@ -341,6 +348,8 @@ impl ExternalLinker for Entry {
|
||||||
debug!("Hash = '{:?}'", hash);
|
debug!("Hash = '{:?}'", hash);
|
||||||
debug!("StoreId = '{:?}'", file_id);
|
debug!("StoreId = '{:?}'", file_id);
|
||||||
|
|
||||||
|
let link_already_exists = store.get(file_id.clone())?.is_some();
|
||||||
|
|
||||||
// retrieve the file from the store, which implicitely creates the entry if it does not
|
// retrieve the file from the store, which implicitely creates the entry if it does not
|
||||||
// exist
|
// exist
|
||||||
let mut file = store
|
let mut file = store
|
||||||
|
@ -375,13 +384,27 @@ impl ExternalLinker for Entry {
|
||||||
// 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
|
||||||
let _ = self.add_internal_link(file.deref_mut())?;
|
let _ = self.add_internal_link(file.deref_mut())?;
|
||||||
debug!("Error adding internal link");
|
debug!("Error adding internal link");
|
||||||
}
|
|
||||||
debug!("Ready iterating");
|
Ok((link_already_exists, file_id))
|
||||||
Ok(())
|
})
|
||||||
|
.filter_map(|res| match res {
|
||||||
|
Ok((exists, entry)) => if exists { Some(Ok(entry)) } else { None },
|
||||||
|
Err(e) => Some(Err(e))
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add an external link to the implementor object
|
/// Add an external link to the implementor object
|
||||||
fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()> {
|
///
|
||||||
|
/// # Return Value
|
||||||
|
///
|
||||||
|
/// (See ExternalLinker::set_external_links())
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
fn add_external_link(&mut self, store: &Store, link: Url) -> Result<Vec<StoreId>> {
|
||||||
// get external links, add this one, save them
|
// get external links, add this one, save them
|
||||||
debug!("Getting links");
|
debug!("Getting links");
|
||||||
self.get_external_links(store)
|
self.get_external_links(store)
|
||||||
|
@ -396,7 +419,16 @@ impl ExternalLinker for Entry {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove an external link from the implementor object
|
/// Remove an external link from the implementor object
|
||||||
fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()> {
|
///
|
||||||
|
/// # Return Value
|
||||||
|
///
|
||||||
|
/// (See ExternalLinker::set_external_links())
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
///
|
||||||
|
fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<Vec<StoreId>> {
|
||||||
// get external links, remove this one, save them
|
// get external links, remove this one, save them
|
||||||
self.get_external_links(store)
|
self.get_external_links(store)
|
||||||
.and_then(|links| {
|
.and_then(|links| {
|
||||||
|
|
Loading…
Reference in a new issue