summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2017-08-28 14:10:40 +0200
committerGitHub <noreply@github.com>2017-08-28 14:10:40 +0200
commitc987130cc1adca9c8074e7e1afe235c4b3f7157e (patch)
treee92280d550d2d601783821e832e6c3f8617a64b5
parentb2d6a881b0902a71055d93072ad0914cccb6003f (diff)
parentc0c62bd1b5c5b9ece1d8289721dc8617987a7885 (diff)
Merge pull request #1018 from matthiasbeyer/remove-toml-ext
Remove toml ext
-rw-r--r--lib/core/libimagrt/Cargo.toml1
-rw-r--r--lib/core/libimagrt/src/configuration.rs7
-rw-r--r--lib/core/libimagrt/src/lib.rs1
-rw-r--r--lib/core/libimagstore/src/lib.rs1
-rw-r--r--lib/core/libimagstore/src/store.rs117
-rw-r--r--lib/core/libimagstore/src/toml_ext.rs894
-rw-r--r--lib/core/libimagstore/src/util.rs2
-rw-r--r--lib/domain/libimagnotes/Cargo.toml1
-rw-r--r--lib/domain/libimagnotes/src/lib.rs1
-rw-r--r--lib/domain/libimagnotes/src/note.rs6
-rw-r--r--lib/entry/libimagentryannotation/Cargo.toml1
-rw-r--r--lib/entry/libimagentryannotation/src/annotateable.rs20
-rw-r--r--lib/entry/libimagentryannotation/src/annotation_fetcher.rs8
-rw-r--r--lib/entry/libimagentryannotation/src/lib.rs1
-rw-r--r--lib/entry/libimagentryfilter/Cargo.toml1
-rw-r--r--lib/entry/libimagentryfilter/src/builtin/header/field_eq.rs4
-rw-r--r--lib/entry/libimagentryfilter/src/builtin/header/field_exists.rs5
-rw-r--r--lib/entry/libimagentryfilter/src/builtin/header/field_grep.rs8
-rw-r--r--lib/entry/libimagentryfilter/src/builtin/header/field_gt.rs6
-rw-r--r--lib/entry/libimagentryfilter/src/builtin/header/field_isempty.rs14
-rw-r--r--lib/entry/libimagentryfilter/src/builtin/header/field_istype.rs4
-rw-r--r--lib/entry/libimagentryfilter/src/builtin/header/field_lt.rs6
-rw-r--r--lib/entry/libimagentryfilter/src/builtin/header/field_predicate.rs5
-rw-r--r--lib/entry/libimagentryfilter/src/builtin/header/version/eq.rs6
-rw-r--r--lib/entry/libimagentryfilter/src/builtin/header/version/gt.rs6
-rw-r--r--lib/entry/libimagentryfilter/src/builtin/header/version/lt.rs6
-rw-r--r--lib/entry/libimagentryfilter/src/lib.rs1
-rw-r--r--lib/entry/libimagentrylink/Cargo.toml1
-rw-r--r--lib/entry/libimagentrylink/src/external.rs10
-rw-r--r--lib/entry/libimagentrylink/src/internal.rs32
-rw-r--r--lib/entry/libimagentrylink/src/lib.rs1
-rw-r--r--lib/entry/libimagentryref/Cargo.toml1
-rw-r--r--lib/entry/libimagentryref/src/flags.rs4
-rw-r--r--lib/entry/libimagentryref/src/lib.rs1
-rw-r--r--lib/entry/libimagentryref/src/reference.rs23
-rw-r--r--lib/entry/libimagentrytag/Cargo.toml1
-rw-r--r--lib/entry/libimagentrytag/src/lib.rs1
-rw-r--r--lib/entry/libimagentrytag/src/tagable.rs10
38 files changed, 219 insertions, 999 deletions
diff --git a/lib/core/libimagrt/Cargo.toml b/lib/core/libimagrt/Cargo.toml
index 4f0f0863..0599e233 100644
--- a/lib/core/libimagrt/Cargo.toml
+++ b/lib/core/libimagrt/Cargo.toml
@@ -23,6 +23,7 @@ itertools = "0.5"
tempfile = "2.1"
ansi_term = "0.9"
is-match = "0.1"
+toml-query = "0.3.0"
libimagstore = { version = "0.4.0", path = "../../../lib/core/libimagstore" }
libimagerror = { version = "0.4.0", path = "../../../lib/core/libimagerror" }
diff --git a/lib/core/libimagrt/src/configuration.rs b/lib/core/libimagrt/src/configuration.rs
index dcb3326b..bc3b52b4 100644
--- a/lib/core/libimagrt/src/configuration.rs
+++ b/lib/core/libimagrt/src/configuration.rs
@@ -133,7 +133,8 @@ impl Configuration {
use self::error::ConfigErrorKind as CEK;
use self::error::MapErrInto;
use libimagerror::into::IntoError;
- use libimagstore::toml_ext::TomlValueExt;
+
+ use toml_query::read::TomlValueReadExt;
v.into_iter()
.map(|s| { debug!("Trying to process '{}'", s); s })
@@ -170,10 +171,10 @@ impl Configuration {
/// Returns None if string cannot be converted.
///
/// Arrays and Tables are not supported and will yield `None`.
-fn into_value(value: Value, s: String) -> Option<Value> {
+fn into_value(value: &Value, s: String) -> Option<Value> {
use std::str::FromStr;
- match value {
+ match *value {
Value::String(_) => Some(Value::String(s)),
Value::Integer(_) => FromStr::from_str(&s[..]).ok().map(Value::Integer),
Value::Float(_) => FromStr::from_str(&s[..]).ok().map(Value::Float),
diff --git a/lib/core/libimagrt/src/lib.rs b/lib/core/libimagrt/src/lib.rs
index 55398013..a28b525f 100644
--- a/lib/core/libimagrt/src/lib.rs
+++ b/lib/core/libimagrt/src/lib.rs
@@ -42,6 +42,7 @@ extern crate ansi_term;
extern crate clap;
extern crate toml;
+extern crate toml_query;
#[macro_use] extern crate is_match;
extern crate libimagstore;
diff --git a/lib/core/libimagstore/src/lib.rs b/lib/core/libimagstore/src/lib.rs
index afb40e80..ba9abe83 100644
--- a/lib/core/libimagstore/src/lib.rs
+++ b/lib/core/libimagstore/src/lib.rs
@@ -60,5 +60,4 @@ pub mod error;
pub mod store;
mod configuration;
pub mod file_abstraction;
-pub mod toml_ext;
diff --git a/lib/core/libimagstore/src/store.rs b/lib/core/libimagstore/src/store.rs
index a0ee33e5..af7e5aaf 100644
--- a/lib/core/libimagstore/src/store.rs
+++ b/lib/core/libimagstore/src/store.rs
@@ -18,6 +18,7 @@
//
use std::collections::HashMap;
+use std::collections::BTreeMap;
use std::ops::Drop;
use std::path::PathBuf;
use std::result::Result as RResult;
@@ -32,15 +33,16 @@ use std::fmt::Debug;
use std::fmt::Error as FMTError;
use toml::Value;
+use toml::value::Table;
use glob::glob;
use walkdir::WalkDir;
use walkdir::Iter as WalkDirIter;
-use error::{StoreError as SE, StoreErrorKind as SEK};
+use error::{StoreError as SE, StoreErrorKind as SEK, ParserError, ParserErrorKind};
use error::MapErrInto;
use storeid::{IntoStoreId, StoreId, StoreIdIterator};
use file_abstraction::FileAbstractionInstance;
-use toml_ext::*;
+
// We re-export the following things so tests can use them
pub use file_abstraction::FileAbstraction;
pub use file_abstraction::FSFileAbstraction;
@@ -1115,6 +1117,96 @@ mod glob_store_iter {
}
+/// Extension trait for top-level toml::Value::Table, will only yield correct results on the
+/// top-level Value::Table, but not on intermediate tables.
+pub trait Header {
+ fn verify(&self) -> Result<()>;
+ fn parse(s: &str) -> RResult<Value, ParserError>;
+ fn default_header() -> Value;
+}
+
+impl Header for Value {
+
+ fn verify(&self) -> Result<()> {
+ match *self {
+ Value::Table(ref t) => verify_header(&t),
+ _ => Err(SE::new(SEK::HeaderTypeFailure, None)),
+ }
+ }
+
+ fn parse(s: &str) -> RResult<Value, ParserError> {
+ use toml::de::from_str;
+
+ from_str(s)
+ .map_err(|_| ParserErrorKind::TOMLParserErrors.into())
+ .and_then(verify_header_consistency)
+ .map(Value::Table)
+ }
+
+ fn default_header() -> Value {
+ let mut m = BTreeMap::new();
+
+ m.insert(String::from("imag"), {
+ let mut imag_map = BTreeMap::<String, Value>::new();
+
+ imag_map.insert(String::from("version"), Value::String(String::from(version!())));
+ imag_map.insert(String::from("links"), Value::Array(vec![]));
+
+ Value::Table(imag_map)
+ });
+
+ Value::Table(m)
+ }
+
+}
+
+fn verify_header_consistency(t: Table) -> RResult<Table, ParserError> {
+ verify_header(&t)
+ .map_err(Box::new)
+ .map_err(|e| ParserErrorKind::HeaderInconsistency.into_error_with_cause(e))
+ .map(|_| t)
+}
+
+fn verify_header(t: &Table) -> Result<()> {
+ if !has_main_section(t) {
+ Err(SE::from(ParserErrorKind::MissingMainSection.into_error()))
+ } else if !has_imag_version_in_main_section(t) {
+ Err(SE::from(ParserErrorKind::MissingVersionInfo.into_error()))
+ } else if !has_only_tables(t) {
+ debug!("Could not verify that it only has tables in its base table");
+ Err(SE::from(ParserErrorKind::NonTableInBaseTable.into_error()))
+ } else {
+ Ok(())
+ }
+}
+
+fn has_only_tables(t: &Table) -> bool {
+ debug!("Verifying that table has only tables");
+ t.iter().all(|(_, x)| is_match!(*x, Value::Table(_)))
+}
+
+fn has_main_section(t: &Table) -> bool {
+ t.contains_key("imag") && is_match!(t.get("imag"), Some(&Value::Table(_)))
+}
+
+fn has_imag_version_in_main_section(t: &Table) -> bool {
+ use semver::Version;
+
+ match *t.get("imag").unwrap() {
+ Value::Table(ref sec) => {
+ sec.get("version")
+ .and_then(|v| {
+ match *v {
+ Value::String(ref s) => Some(Version::parse(&s[..]).is_ok()),
+ _ => Some(false),
+ }
+ })
+ .unwrap_or(false)
+ }
+ _ => false,
+ }
+}
+
#[cfg(test)]
mod test {
@@ -1122,13 +1214,14 @@ mod test {
use std::collections::BTreeMap;
use storeid::StoreId;
+ use store::has_main_section;
+ use store::has_imag_version_in_main_section;
+ use store::verify_header_consistency;
use toml::Value;
#[test]
fn test_imag_section() {
- use toml_ext::has_main_section;
-
let mut map = BTreeMap::new();
map.insert("imag".into(), Value::Table(BTreeMap::new()));
@@ -1137,8 +1230,6 @@ mod test {
#[test]
fn test_imag_invalid_section_type() {
- use toml_ext::has_main_section;
-
let mut map = BTreeMap::new();
map.insert("imag".into(), Value::Boolean(false));
@@ -1147,8 +1238,6 @@ mod test {
#[test]
fn test_imag_abscent_main_section() {
- use toml_ext::has_main_section;
-
let mut map = BTreeMap::new();
map.insert("not_imag".into(), Value::Boolean(false));
@@ -1157,8 +1246,6 @@ mod test {
#[test]
fn test_main_section_without_version() {
- use toml_ext::has_imag_version_in_main_section;
-
let mut map = BTreeMap::new();
map.insert("imag".into(), Value::Table(BTreeMap::new()));
@@ -1167,8 +1254,6 @@ mod test {
#[test]
fn test_main_section_with_version() {
- use toml_ext::has_imag_version_in_main_section;
-
let mut map = BTreeMap::new();
let mut sub = BTreeMap::new();
sub.insert("version".into(), Value::String("0.0.0".into()));
@@ -1179,8 +1264,6 @@ mod test {
#[test]
fn test_main_section_with_version_in_wrong_type() {
- use toml_ext::has_imag_version_in_main_section;
-
let mut map = BTreeMap::new();
let mut sub = BTreeMap::new();
sub.insert("version".into(), Value::Boolean(false));
@@ -1191,8 +1274,6 @@ mod test {
#[test]
fn test_verification_good() {
- use toml_ext::verify_header_consistency;
-
let mut header = BTreeMap::new();
let sub = {
let mut sub = BTreeMap::new();
@@ -1208,8 +1289,6 @@ mod test {
#[test]
fn test_verification_invalid_versionstring() {
- use toml_ext::verify_header_consistency;
-
let mut header = BTreeMap::new();
let sub = {
let mut sub = BTreeMap::new();
@@ -1226,8 +1305,6 @@ mod test {
#[test]
fn test_verification_current_version() {
- use toml_ext::verify_header_consistency;
-
let mut header = BTreeMap::new();
let sub = {
let mut sub = BTreeMap::new();
diff --git a/lib/core/libimagstore/src/toml_ext.rs b/lib/core/libimagstore/src/toml_ext.rs
deleted file mode 100644
index 9c0ae540..00000000
--- a/lib/core/libimagstore/src/toml_ext.rs
+++ /dev/null
@@ -1,894 +0,0 @@
-//
-// imag - the personal information management suite for the commandline
-// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; version
-// 2.1 of the License.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-//
-
-use std::result::Result as RResult;
-use std::collections::BTreeMap;
-
-use toml::Value;
-
-use store::Result;
-use error::StoreError as SE;
-use error::StoreErrorKind as SEK;
-use error::{ParserErrorKind, ParserError};
-use libimagerror::into::IntoError;
-
-type Table = BTreeMap<String, Value>;
-
-pub trait TomlValueExt {
- fn insert_with_sep(&mut self, spec: &str, sep: char, v: Value) -> Result<bool>;
- fn set_with_sep(&mut self, spec: &str, sep: char, v: Value) -> Result<Option<Value>>;
- fn read_with_sep(&self, spec: &str, splitchr: char) -> Result<Option<Value>>;
- fn delete_with_sep(&mut self, spec: &str, splitchr: char) -> Result<Option<Value>>;
-
- #[inline]
- fn insert(&mut self, spec: &str, v: Value) -> Result<bool> {
- self.insert_with_sep(spec, '.', v)
- }
-
- #[inline]
- fn set(&mut self, spec: &str, v: Value) -> Result<Option<Value>> {
- self.set_with_sep(spec, '.', v)
- }
-
- #[inline]
- fn read(&self, spec: &str) -> Result<Option<Value>> {
- self.read_with_sep(spec, '.')
- }
-
- #[inline]
- fn delete(&mut self, spec: &str) -> Result<Option<Value>> {
- self.delete_with_sep(spec, '.')
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-enum Token {
- Key(String),
- Index(usize),
-}
-
-impl TomlValueExt for Value {
- /**
- * Insert a header field by a string-spec
- *
- * ```ignore
- * insert("something.in.a.field", Boolean(true));
- * ```
- *
- * If an array field was accessed which is _out of bounds_ of the array available, the element
- * is appended to the array.
- *
- * Inserts a Boolean in the section "something" -> "in" -> "a" -> "field"
- * A JSON equivalent would be
- *
- * {
- * something: {
- * in: {
- * a: {
- * field: true
- * }
- * }
- * }
- * }
- *
- * Returns true if header field was set, false if there is already a value
- */
- fn insert_with_sep(&mut self, spec: &str, sep: char, v: Value) -> Result<bool> {
- let (destination, value) = try!(setup(self, spec, sep));
-
- // There is already an value at this place
- if value.extract(&destination).is_ok() {
- return Ok(false);
- }
-
- match destination {
- // if the destination shall be an map key
- Token::Key(ref s) => match *value {
- /*
- * Put it in there if we have a map
- */
- Value::Table(ref mut t) => { t.insert(s.clone(), v); },
-
- /*
- * Fail if there is no map here
- */
- _ => return Err(SEK::HeaderPathTypeFailure.into_error()),
- },
-
- // if the destination shall be an array
- Token::Index(i) => match *value {
-
- /*
- * Put it in there if we have an array
- */
- Value::Array(ref mut a) => {
- a.push(v); // push to the end of the array
-
- // if the index is inside the array, we swap-remove the element at this
- // index
- if a.len() < i {
- a.swap_remove(i);
- }
- },
-
- /*
- * Fail if there is no array here
- */
- _ => return Err(SEK::HeaderPathTypeFailure.into_error()),
- },
- }
-
- Ok(true)
- }
-
- /**
- * Set a header field by a string-spec
- *
- * ```ignore
- * set("something.in.a.field", Boolean(true));
- * ```
- *
- * Sets a Boolean in the section "something" -> "in" -> "a" -> "field"
- * A JSON equivalent would be
- *
- * {
- * something: {
- * in: {
- * a: {
- * field: true
- * }
- * }
- * }
- * }
- *
- * If there is already a value at this place, this value will be overridden and the old value
- * will be returned
- */
- fn set_with_sep(&mut self, spec: &str, sep: char, v: Value) -> Result<Option<Value>> {
- let (destination, value) = try!(setup(self, spec, sep));
-
- match destination {
- // if the destination shall be an map key->value
- Token::Key(ref s) => match *value {
- /*
- * Put it in there if we have a map
- */
- Value::Table(ref mut t) => {
- debug!("Matched Key->Table");
- return Ok(t.insert(s.clone(), v));
- }
-
- /*
- * Fail if there is no map here
- */
- _ => {
- debug!("Matched Key->NON-Table");
- return Err(SEK::HeaderPathTypeFailure.into_error());
- }
- },
-
- // if the destination shall be an array
- Token::Index(i) => match *value {
-
- /*
- * Put it in there if we have an array
- */
- Value::Array(ref mut a) => {
- debug!("Matched Index->Array");
- a.push(v); // push to the end of the array
-
- // if the index is inside the array, we swap-remove the element at this
- // index
- if a.len() > i {
- debug!("Swap-Removing in Array {:?}[{:?}] <- {:?}", a, i, a[a.len()-1]);
- return Ok(Some(a.swap_remove(i)));
- }
-
- debug!("Appended");
- return Ok(None);
- },
-
- /*
- * Fail if there is no array here
- */
- _ => {
- debug!("Matched Index->NON-Array");
- return Err(SEK::HeaderPathTypeFailure.into_error());
- },
- },
- }
- }
-
- /**
- * Read a header field by a string-spec
- *
- * ```ignore
- * let value = read("something.in.a.field");
- * ```
- *
- * Reads a Value in the section "something" -> "in" -> "a" -> "field"
- * A JSON equivalent would be
- *
- * {
- * something: {
- * in: {
- * a: {
- * field: true
- * }
- * }
- * }
- * }
- *
- * If there is no a value at this place, None will be returned. This also holds true for Arrays
- * which are accessed at an index which is not yet there, even if the accessed index is much
- * larger than the array length.
- */
- fn read_with_sep(&self, spec: &str, splitchr: char) -> Result<Option<Value>> {
- let tokens = try!(tokenize(spec, splitchr));
-
- let mut header_clone = self.clone(); // we clone as READing is simpler this way
- // walk N-1 tokens
- match walk_header(&mut header_clone, tokens) {
- Err(e) => match e.err_type() {
- // We cannot find the header key, as there is no path to it
- SEK::HeaderKeyNotFound => Ok(None),
- _ => Err(e),
- },
- Ok(v) => Ok(Some(v.clone())),
- }
- }
-
- fn delete_with_sep(&mut self, spec: &str, splitchr: char) -> Result<Option<Value>> {
- let (destination, value) = try!(setup(self, spec, splitchr));
-
- match destination {
- // if the destination shall be an map key->value
- Token::Key(ref s) => match *value {
- Value::Table(ref mut t) => {
- debug!("Matched Key->Table, removing {:?}", s);
- return Ok(t.remove(s));
- },
- _ => {
- debug!("Matched Key->NON-Table");
- return Err(SEK::HeaderPathTypeFailure.into_error());
- }
- },
-
- // if the destination shall be an array
- Token::Index(i) => match *value {
-
- // if the index is inside the array, we swap-remove the element at this
- // index
- Value::Array(ref mut a) => if a.len() > i {
- debug!("Removing in Array {:?}[{:?}]", a, i);
- return Ok(Some(a.remove(i)));
- } else {
- return Ok(None);
- },
- _ => {
- debug!("Matched Index->NON-Array");
- return Err(SEK::HeaderPathTypeFailure.into_error());
- },
- },
- }
- }
-
-}
-
-fn setup<'a>(v: &'a mut Value, spec: &str, sep: char)
- -> Result<(Token, &'a mut Value)>
-{
- let tokens = try!(tokenize(spec, sep));
- debug!("tokens = {:?}", tokens);
-
- let destination = try!(tokens.iter().last().cloned().ok_or(SEK::HeaderPathSyntaxError.into_error()));
- debug!("destination = {:?}", destination);
-
- let path_to_dest : Vec<Token> = tokens[..(tokens.len() - 1)].into(); // N - 1 tokens
- let value = try!(walk_header(v, path_to_dest)); // walk N-1 tokens
-
- debug!("walked value = {:?}", value);
-
- Ok((destination, value))
-}
-
-fn tokenize(spec: &str, splitchr: char) -> Result<Vec<Token>> {
- use std::str::FromStr;
-
- spec.split(splitchr)
- .map(|s| usize::from_str(s).map(Token::Index).or_else(|_| Ok(Token::Key(String::from(s)))))
- .collect()
-}
-
-fn walk_header(v: &mut Value, tokens: Vec<Token>) -> Result<&mut Value> {
- use std::vec::IntoIter;
-
- fn walk_iter<'a>(v: Result<&'a mut Value>, i: &mut IntoIter<Token>) -> Result<&'a mut Value> {
- let next = i.next();
- v.and_then(move |value| if let Some(token) = next {
- walk_iter(value.extract(&token), i)
- } else {
- Ok(value)
- })
- }
-
- walk_iter(Ok(v), &mut tokens.into_iter())
-}
-
-trait Extract {
- fn extract<'a>(&'a mut self, &Token) -> Result<&'a mut Self>;
-}
-
-impl Extract for Value {
- fn extract<'a>(&'a mut self, token: &Token) -> Result<&'a mut Value> {
- match *token {
- // on Token::Key extract from Value::Table
- Token::Key(ref s) => match *self {
- Value::Table(ref mut t) =>
- t.get_mut(&s[..]).ok_or(SEK::HeaderKeyNotFound.into_error()),
-
- _ => Err(SEK::HeaderPathTypeFailure.into_error()),
- },
-
- // on Token::Index extract from Value::Array
- Token::Index(i) => match *self {
- Value::Array(ref mut a) => if a.len() < i {
- Err(SEK::HeaderKeyNotFound.into_error())
- } else {
- Ok(&mut a[i])
- },
-
- _ => Err(SEK::HeaderPathTypeFailure.into_error()),
- }
- }
- }
-}
-
-pub type EntryResult<T> = RResult<T, ParserError>;
-
-/// Extension trait for top-level toml::Value::Table, will only yield correct results on the
-/// top-level Value::Table, but not on intermediate tables.
-pub trait Header {
- fn verify(&self) -> Result<()>;
- fn parse(s: &str) -> EntryResult<Value>;
- fn default_header() -> Value;
-}
-
-impl Header for Value {
-
- fn verify(&self) -> Result<()> {
- match *self {
- Value::Table(ref t) => verify_header(&t),
- _ => Err(SE::new(SEK::HeaderTypeFailure, None)),
- }
- }
-
- fn parse(s: &str) -> EntryResult<Value> {
- use toml::de::from_str;
-
- from_str(s)
- .map_err(|_| ParserErrorKind::TOMLParserErrors.into())
- .and_then(verify_header_consistency)
- .map(Value::Table)
- }
-
- fn default_header() -> Value {
- let mut m = BTreeMap::new();
-
- m.insert(String::from("imag"), {
- let mut imag_map = BTreeMap::<String, Value>::new();
-
- imag_map.insert(String::from("version"), Value::String(String::from(version!())));
- imag_map.insert(String::from("links"), Value::Array(vec![]));
-
- Value::Table(imag_map)
- });
-
- Value::Table(m)
- }
-
-}
-
-pub fn verify_header_consistency(t: Table) -> EntryResult<Table> {
- verify_header(&t)
- .map_err(Box::new)
- .map_err(|e| ParserErrorKind::HeaderInconsistency.into_error_with_cause(e))
- .map(|_| t)
-}
-
-fn verify_header(t: &Table) -> Result<()> {
- if !has_main_section(t) {
- Err(SE::from(ParserErrorKind::MissingMainSection.into_error()))
- } else if !has_imag_version_in_main_section(t) {
- Err(SE::from(ParserErrorKind::MissingVersionInfo.into_error()))
- } else if !has_only_tables(t) {
- debug!("Could not verify that it only has tables in its base table");
- Err(SE::from(ParserErrorKind::NonTableInBaseTable.into_error()))
- } else {
- Ok(())
- }
-}
-
-fn has_only_tables(t: &Table) -> bool {
- debug!("Verifying that table has only tables");
- t.iter().all(|(_, x)| is_match!(*x, Value::Table(_)))
-}
-
-pub fn has_main_section(t: &Table) -> bool {
- t.contains_key("imag") && is_match!(t.get("imag"), Some(&Value::Table(_)))
-}
-
-pub fn has_imag_version_in_main_section(t: &Table) -> bool {
- use semver::Version;
-
- match *t.get("imag").unwrap() {
- Value::Table(ref sec) => {
- sec.get("version")
- .and_then(|v| {
- match *v {
- Value::String(ref s) => Some(Version::parse(&s[..]).is_ok()),
- _ => Some(false),
- }
- })
- .unwrap_or(false)
- }
- _ => false,
- }
-}
-
-
-#[cfg(test)]
-mod test {
- extern crate env_logger;
- use super::TomlValueExt;
- use super::{tokenize, walk_header};
- use super::Token;
-
- use std::collections::BTreeMap;
-
- use toml::Value;
-
- #[test]
- fn test_walk_header_simple() {
- let tokens = tokenize("a", '.').unwrap();
- assert!