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:
Matthias Beyer 2019-06-23 21:06:11 +02:00
parent cdc90f7be7
commit ed8546c7dd
4 changed files with 105 additions and 32 deletions

View file

@ -27,15 +27,21 @@ url = "1.5"
sha-1 = "0.7" sha-1 = "0.7"
hex = "0.3" hex = "0.3"
is-match = "0.1" is-match = "0.1"
toml-query = "0.9"
failure = "0.1" failure = "0.1"
failure_derive = "0.1" failure_derive = "0.1"
serde = "1"
serde_derive = "1"
libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagstore" } libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagstore" }
libimagerror = { version = "0.10.0", path = "../../../lib/core/libimagerror" } libimagerror = { version = "0.10.0", path = "../../../lib/core/libimagerror" }
libimagutil = { version = "0.10.0", path = "../../../lib/etc/libimagutil" } libimagutil = { version = "0.10.0", path = "../../../lib/etc/libimagutil" }
libimagentrylink = { version = "0.10.0", path = "../../../lib/entry/libimagentrylink" } libimagentrylink = { version = "0.10.0", path = "../../../lib/entry/libimagentrylink" }
[dependencies.toml-query]
version = "0.9"
default-features = false
features = [ "typed" ]
[dev-dependencies] [dev-dependencies]
env_logger = "0.5" env_logger = "0.5"

View file

@ -175,7 +175,7 @@ impl<'a> Iterator for UrlIter<'a> {
.and_then(|f| { .and_then(|f| {
debug!("Store::retrieve({:?}) succeeded", id); debug!("Store::retrieve({:?}) succeeded", id);
debug!("getting uri link from file now"); 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_str("Error happened while getting link URI from FLE")
.map_dbg_err(|e| format!("URL -> Err = {:?}", e)) .map_dbg_err(|e| format!("URL -> Err = {:?}", e))
}) })

View file

@ -55,6 +55,8 @@ extern crate toml_query;
extern crate url; extern crate url;
extern crate sha1; extern crate sha1;
extern crate hex; extern crate hex;
extern crate serde;
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate failure; #[macro_use] extern crate failure;
#[cfg(test)] #[cfg(test)]

View file

@ -22,55 +22,120 @@ use failure::ResultExt;
use failure::Fallible as Result; use failure::Fallible as Result;
use failure::err_msg; use failure::err_msg;
use url::Url; use url::Url;
use toml_query::read::Partial;
use toml_query::insert::TomlValueInsertExt;
use toml::Value;
use libimagstore::store::Entry; use libimagstore::store::Entry;
use libimagerror::errors::ErrorMsg as EM; use libimagerror::errors::ErrorMsg as EM;
use toml_query::read::TomlValueReadTypeExt; use toml_query::read::TomlValueReadExt;
pub trait Link { pub trait Link {
fn get_link_uri_from_filelockentry(&self) -> Result<Option<Url>>;
fn get_url(&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 { impl Link for Entry {
fn get_link_uri_from_filelockentry(&self) -> Result<Option<Url>> { /// Get the URL from entry Entry
self.get_header() ///
.read_string("url.uri") /// # 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(format_err!("Error reading header 'url.uri' from '{}'", self.get_location()))
.context(EM::EntryHeaderReadError) .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) .map_err(Error::from)
.and_then(|opt| match opt { .context(format_err!("Failed to parse URL: '{}'", url))
None => Ok(None), .context(err_msg("Invalid URI"))
Some(ref s) => { .map_err(Error::from)
debug!("Found url, parsing: {:?}", s); .map(Some)
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("Failed to get link URI from entry") .context("Failed to get link URI from entry")
.map_err(Error::from) .map_err(Error::from)
} }
fn get_url(&self) -> Result<Option<Url>> { fn set_url(&mut self, url: Url) -> Result<()> {
match self.get_header().read_string("url.uri")? { let val = Value::String(url.to_string());
None => Ok(None), self.get_header_mut().insert_serialized("url.uri", val)?;
Some(ref s) => Url::parse(&s[..])
.context(format_err!("Failed to parse URL: '{}'", s)) debug!("Setting URL worked");
.map(Some) Ok(())
.map_err(Error::from) }
.context(EM::EntryHeaderReadError) }
.map_err(Error::from),
#[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),
} }
} }
} }