From ed8546c7ddfe8f2ecb74e31554ed94750214ae72 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 23 Jun 2019 21:06:11 +0200 Subject: [PATCH] Reimplement link module with header Partial This patch reimplements the "link" module using the `toml_query::read::Partial` feature. Signed-off-by: Matthias Beyer --- lib/entry/libimagentryurl/Cargo.toml | 8 +- lib/entry/libimagentryurl/src/iter.rs | 2 +- lib/entry/libimagentryurl/src/lib.rs | 2 + lib/entry/libimagentryurl/src/link.rs | 125 +++++++++++++++++++------- 4 files changed, 105 insertions(+), 32 deletions(-) diff --git a/lib/entry/libimagentryurl/Cargo.toml b/lib/entry/libimagentryurl/Cargo.toml index 2c8ede95..5b17404b 100644 --- a/lib/entry/libimagentryurl/Cargo.toml +++ b/lib/entry/libimagentryurl/Cargo.toml @@ -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" diff --git a/lib/entry/libimagentryurl/src/iter.rs b/lib/entry/libimagentryurl/src/iter.rs index 50de8d01..ddec1d6c 100644 --- a/lib/entry/libimagentryurl/src/iter.rs +++ b/lib/entry/libimagentryurl/src/iter.rs @@ -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)) }) diff --git a/lib/entry/libimagentryurl/src/lib.rs b/lib/entry/libimagentryurl/src/lib.rs index 7d08ba14..4333a734 100644 --- a/lib/entry/libimagentryurl/src/lib.rs +++ b/lib/entry/libimagentryurl/src/lib.rs @@ -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)] diff --git a/lib/entry/libimagentryurl/src/link.rs b/lib/entry/libimagentryurl/src/link.rs index 716cf1a7..3ae5aa70 100644 --- a/lib/entry/libimagentryurl/src/link.rs +++ b/lib/entry/libimagentryurl/src/link.rs @@ -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>; - fn get_url(&self) -> Result>; - + fn set_url(&mut self, url: Url) -> Result<()>; } +#[derive(Deserialize, Serialize, Debug)] +pub(crate) struct UrlHeader { + pub uri: Option, +} + +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> { - 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> { + let partial = self.get_header() + .read_partial::() .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> { - 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), } } } -