Reimplement link module with header Partial
This patch reimplements the "link" module using the `toml_query::read::Partial` feature. Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
parent
cdc90f7be7
commit
ed8546c7dd
4 changed files with 105 additions and 32 deletions
|
@ -27,15 +27,21 @@ url = "1.5"
|
|||
sha-1 = "0.7"
|
||||
hex = "0.3"
|
||||
is-match = "0.1"
|
||||
toml-query = "0.9"
|
||||
failure = "0.1"
|
||||
failure_derive = "0.1"
|
||||
serde = "1"
|
||||
serde_derive = "1"
|
||||
|
||||
libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagstore" }
|
||||
libimagerror = { version = "0.10.0", path = "../../../lib/core/libimagerror" }
|
||||
libimagutil = { version = "0.10.0", path = "../../../lib/etc/libimagutil" }
|
||||
libimagentrylink = { version = "0.10.0", path = "../../../lib/entry/libimagentrylink" }
|
||||
|
||||
[dependencies.toml-query]
|
||||
version = "0.9"
|
||||
default-features = false
|
||||
features = [ "typed" ]
|
||||
|
||||
[dev-dependencies]
|
||||
env_logger = "0.5"
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ impl<'a> Iterator for UrlIter<'a> {
|
|||
.and_then(|f| {
|
||||
debug!("Store::retrieve({:?}) succeeded", id);
|
||||
debug!("getting uri link from file now");
|
||||
f.get_link_uri_from_filelockentry()
|
||||
f.get_url()
|
||||
.map_dbg_str("Error happened while getting link URI from FLE")
|
||||
.map_dbg_err(|e| format!("URL -> Err = {:?}", e))
|
||||
})
|
||||
|
|
|
@ -55,6 +55,8 @@ extern crate toml_query;
|
|||
extern crate url;
|
||||
extern crate sha1;
|
||||
extern crate hex;
|
||||
extern crate serde;
|
||||
#[macro_use] extern crate serde_derive;
|
||||
#[macro_use] extern crate failure;
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -22,55 +22,120 @@ use failure::ResultExt;
|
|||
use failure::Fallible as Result;
|
||||
use failure::err_msg;
|
||||
use url::Url;
|
||||
use toml_query::read::Partial;
|
||||
use toml_query::insert::TomlValueInsertExt;
|
||||
use toml::Value;
|
||||
|
||||
use libimagstore::store::Entry;
|
||||
use libimagerror::errors::ErrorMsg as EM;
|
||||
|
||||
use toml_query::read::TomlValueReadTypeExt;
|
||||
use toml_query::read::TomlValueReadExt;
|
||||
|
||||
pub trait Link {
|
||||
|
||||
fn get_link_uri_from_filelockentry(&self) -> Result<Option<Url>>;
|
||||
|
||||
fn get_url(&self) -> Result<Option<Url>>;
|
||||
|
||||
fn set_url(&mut self, url: Url) -> Result<()>;
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub(crate) struct UrlHeader {
|
||||
pub uri: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for UrlHeader {
|
||||
fn default() -> Self {
|
||||
UrlHeader {
|
||||
uri: None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Partial<'a> for UrlHeader {
|
||||
const LOCATION: &'static str = "url";
|
||||
type Output = Self;
|
||||
}
|
||||
|
||||
|
||||
impl Link for Entry {
|
||||
|
||||
fn get_link_uri_from_filelockentry(&self) -> Result<Option<Url>> {
|
||||
self.get_header()
|
||||
.read_string("url.uri")
|
||||
/// Get the URL from entry Entry
|
||||
///
|
||||
/// # Notice
|
||||
///
|
||||
/// This actually returns the header field of the entry, parsed as URL
|
||||
///
|
||||
///
|
||||
fn get_url(&self) -> Result<Option<Url>> {
|
||||
let partial = self.get_header()
|
||||
.read_partial::<UrlHeader>()
|
||||
.context(format_err!("Error reading header 'url.uri' from '{}'", self.get_location()))
|
||||
.context(EM::EntryHeaderReadError)
|
||||
.map_err(Error::from)?
|
||||
.unwrap_or_else(|| Default::default());
|
||||
|
||||
let url = match partial.uri {
|
||||
Some(uri) => uri,
|
||||
None => return Ok(None),
|
||||
};
|
||||
|
||||
debug!("Found url, parsing: {:?}", url);
|
||||
Url::parse(&url)
|
||||
.map_err(Error::from)
|
||||
.and_then(|opt| match opt {
|
||||
None => Ok(None),
|
||||
Some(ref s) => {
|
||||
debug!("Found url, parsing: {:?}", s);
|
||||
Url::parse(&s[..])
|
||||
.map_err(Error::from)
|
||||
.context(format_err!("Failed to parse URL: '{}'", s))
|
||||
.context(err_msg("Invalid URI"))
|
||||
.map_err(Error::from)
|
||||
.map(Some)
|
||||
},
|
||||
})
|
||||
.context(format_err!("Failed to parse URL: '{}'", url))
|
||||
.context(err_msg("Invalid URI"))
|
||||
.map_err(Error::from)
|
||||
.map(Some)
|
||||
.context("Failed to get link URI from entry")
|
||||
.map_err(Error::from)
|
||||
}
|
||||
|
||||
fn get_url(&self) -> Result<Option<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))
|
||||
.map(Some)
|
||||
.map_err(Error::from)
|
||||
.context(EM::EntryHeaderReadError)
|
||||
.map_err(Error::from),
|
||||
fn set_url(&mut self, url: Url) -> Result<()> {
|
||||
let val = Value::String(url.to_string());
|
||||
self.get_header_mut().insert_serialized("url.uri", val)?;
|
||||
|
||||
debug!("Setting URL worked");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use libimagstore::store::Store;
|
||||
|
||||
fn setup_logging() {
|
||||
let _ = env_logger::try_init();
|
||||
}
|
||||
|
||||
pub fn get_store() -> Store {
|
||||
Store::new_inmemory(PathBuf::from("/"), &None).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_header_set_correctly() {
|
||||
setup_logging();
|
||||
let store = get_store();
|
||||
let mut e = store.retrieve(PathBuf::from("urlentry")).unwrap();
|
||||
let url = Url::parse("http://google.de").unwrap();
|
||||
|
||||
assert!(e.set_url(url).is_ok());
|
||||
debug!("Fetch header: {:?}", e.get_header());
|
||||
|
||||
let url = e.get_header().read("url.uri");
|
||||
|
||||
debug!("Fetched header: {:?}", url);
|
||||
|
||||
assert!(url.is_ok());
|
||||
let url = url.unwrap();
|
||||
|
||||
assert!(url.is_some());
|
||||
let url = url.unwrap();
|
||||
|
||||
match url {
|
||||
Value::String(ref s) => assert_eq!("http://google.de/", s),
|
||||
_ => assert!(false),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue