Rewrite libimagentrylink::external::Link to be a trait
This commit is contained in:
parent
29d93a73f0
commit
4b42b3328d
1 changed files with 41 additions and 42 deletions
|
@ -35,12 +35,12 @@ use std::collections::BTreeMap;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use libimagstore::store::Entry;
|
use libimagstore::store::Entry;
|
||||||
use libimagstore::store::FileLockEntry;
|
|
||||||
use libimagstore::store::Store;
|
use libimagstore::store::Store;
|
||||||
use libimagstore::storeid::StoreId;
|
use libimagstore::storeid::StoreId;
|
||||||
use libimagstore::storeid::IntoStoreId;
|
use libimagstore::storeid::IntoStoreId;
|
||||||
use libimagstore::toml_ext::TomlValueExt;
|
use libimagstore::toml_ext::TomlValueExt;
|
||||||
use libimagutil::debug_result::*;
|
use libimagutil::debug_result::*;
|
||||||
|
use libimagerror::into::IntoError;
|
||||||
|
|
||||||
use error::LinkError as LE;
|
use error::LinkError as LE;
|
||||||
use error::LinkErrorKind as LEK;
|
use error::LinkErrorKind as LEK;
|
||||||
|
@ -56,37 +56,32 @@ use url::Url;
|
||||||
use crypto::sha1::Sha1;
|
use crypto::sha1::Sha1;
|
||||||
use crypto::digest::Digest;
|
use crypto::digest::Digest;
|
||||||
|
|
||||||
/// "Link" Type, just an abstraction over `FileLockEntry` to have some convenience internally.
|
pub trait Link {
|
||||||
pub struct Link<'a> {
|
|
||||||
link: FileLockEntry<'a>
|
fn get_link_uri_from_filelockentry(&self) -> Result<Option<Url>>;
|
||||||
|
|
||||||
|
fn get_url(&self) -> Result<Option<Url>>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Link<'a> {
|
impl Link for Entry {
|
||||||
|
|
||||||
pub fn new(fle: FileLockEntry<'a>) -> Link<'a> {
|
fn get_link_uri_from_filelockentry(&self) -> Result<Option<Url>> {
|
||||||
Link { link: fle }
|
self.get_header()
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a link Url object from a `FileLockEntry`, ignore errors.
|
|
||||||
fn get_link_uri_from_filelockentry(file: &FileLockEntry<'a>) -> Option<Url> {
|
|
||||||
file.get_header()
|
|
||||||
.read("imag.content.url")
|
.read("imag.content.url")
|
||||||
.ok()
|
.map_err_into(LEK::EntryHeaderReadError)
|
||||||
.and_then(|opt| match opt {
|
.and_then(|opt| match opt {
|
||||||
Some(Value::String(s)) => {
|
Some(Value::String(s)) => {
|
||||||
debug!("Found url, parsing: {:?}", s);
|
debug!("Found url, parsing: {:?}", s);
|
||||||
Url::parse(&s[..]).ok()
|
Url::parse(&s[..]).map_err_into(LEK::InvalidUri).map(Some)
|
||||||
},
|
},
|
||||||
_ => None
|
Some(_) => Err(LEK::LinkParserFieldTypeError.into_error()),
|
||||||
|
None => Ok(None),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_url(&self) -> Result<Option<Url>> {
|
fn get_url(&self) -> Result<Option<Url>> {
|
||||||
let opt = self.link
|
match self.get_header().read("imag.content.url") {
|
||||||
.get_header()
|
|
||||||
.read("imag.content.url");
|
|
||||||
|
|
||||||
match opt {
|
|
||||||
Ok(Some(Value::String(s))) => {
|
Ok(Some(Value::String(s))) => {
|
||||||
Url::parse(&s[..])
|
Url::parse(&s[..])
|
||||||
.map(Some)
|
.map(Some)
|
||||||
|
@ -259,23 +254,32 @@ pub mod iter {
|
||||||
type Item = Result<Url>;
|
type Item = Result<Url>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
use super::get_external_link_from_file;
|
use external::Link;
|
||||||
|
|
||||||
self.0
|
loop {
|
||||||
.next()
|
let next = self.0
|
||||||
.map(|id| {
|
.next()
|
||||||
debug!("Retrieving entry for id: '{:?}'", id);
|
.map(|id| {
|
||||||
self.1
|
debug!("Retrieving entry for id: '{:?}'", id);
|
||||||
.retrieve(id.clone())
|
self.1
|
||||||
.map_err_into(LEK::StoreReadError)
|
.retrieve(id.clone())
|
||||||
.map_dbg_err(|_| format!("Retrieving entry for id: '{:?}' failed", id))
|
.map_err_into(LEK::StoreReadError)
|
||||||
.and_then(|f| {
|
.map_dbg_err(|_| format!("Retrieving entry for id: '{:?}' failed", id))
|
||||||
debug!("Store::retrieve({:?}) succeeded", id);
|
.and_then(|f| {
|
||||||
debug!("getting external link from file now");
|
debug!("Store::retrieve({:?}) succeeded", id);
|
||||||
get_external_link_from_file(&f)
|
debug!("getting external link from file now");
|
||||||
.map_dbg_err(|e| format!("URL -> Err = {:?}", e))
|
f.get_link_uri_from_filelockentry()
|
||||||
})
|
.map_dbg_err(|e| format!("URL -> Err = {:?}", e))
|
||||||
})
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
match next {
|
||||||
|
Some(Ok(Some(link))) => return Some(Ok(link)),
|
||||||
|
Some(Ok(None)) => continue,
|
||||||
|
Some(Err(e)) => return Some(Err(e)),
|
||||||
|
None => return None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -289,11 +293,6 @@ pub fn is_external_link_storeid<A: AsRef<StoreId> + Debug>(id: A) -> bool {
|
||||||
id.as_ref().local().starts_with("links/external")
|
id.as_ref().local().starts_with("links/external")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_external_link_from_file(entry: &FileLockEntry) -> Result<Url> {
|
|
||||||
Link::get_link_uri_from_filelockentry(entry) // TODO: Do not hide error by using this function
|
|
||||||
.ok_or(LE::new(LEK::StoreReadError, None))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implement `ExternalLinker` for `Entry`, hiding the fact that there is no such thing as an external
|
/// 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
|
/// 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.
|
/// entry in the store can only have one external link.
|
||||||
|
|
Loading…
Reference in a new issue