2016-01-18 13:12:12 +00:00
|
|
|
use std::error::Error;
|
|
|
|
use std::result::Result as RResult;
|
|
|
|
|
2016-01-18 13:56:37 +00:00
|
|
|
use toml::{Table, Value};
|
2016-01-12 17:50:57 +00:00
|
|
|
|
2016-01-18 13:12:12 +00:00
|
|
|
pub mod error {
|
|
|
|
use std::fmt::{Debug, Display, Formatter};
|
|
|
|
use std::fmt;
|
|
|
|
use std::error::Error;
|
|
|
|
use toml;
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
pub enum ParserErrorKind {
|
|
|
|
TOMLParserErrors,
|
|
|
|
MissingMainSection,
|
2016-01-18 13:56:37 +00:00
|
|
|
MissingVersionInfo,
|
2016-01-18 13:12:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct ParserError {
|
|
|
|
kind: ParserErrorKind,
|
|
|
|
cause: Option<Box<Error>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ParserError {
|
|
|
|
|
|
|
|
pub fn new(k: ParserErrorKind, cause: Option<Box<Error>>) -> ParserError {
|
|
|
|
ParserError {
|
|
|
|
kind: k,
|
|
|
|
cause: cause,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Debug for ParserError {
|
|
|
|
|
|
|
|
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
|
|
|
try!(write!(f, "{:?}", self.description()));
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for ParserError {
|
|
|
|
|
|
|
|
fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
|
|
|
|
try!(write!(f, "{}", self.description()));
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Error for ParserError {
|
|
|
|
|
|
|
|
fn description(&self) -> &str {
|
|
|
|
match self.kind {
|
|
|
|
ParserErrorKind::TOMLParserErrors => "Several TOML-Parser-Errors",
|
2016-01-18 13:56:37 +00:00
|
|
|
ParserErrorKind::MissingMainSection => "Missing main section",
|
|
|
|
ParserErrorKind::MissingVersionInfo => "Missing version information in main section",
|
2016-01-18 13:12:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn cause(&self) -> Option<&Error> {
|
|
|
|
self.cause.as_ref().map(|e| &**e)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
use self::error::ParserErrorKind;
|
|
|
|
use self::error::ParserError;
|
|
|
|
|
2016-01-21 20:28:18 +00:00
|
|
|
/**
|
|
|
|
* EntryHeader
|
|
|
|
*
|
|
|
|
* This is basically a wrapper around toml::Table which provides convenience to the user of the
|
|
|
|
* librray.
|
|
|
|
*/
|
2016-01-16 18:16:41 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2016-01-12 17:50:57 +00:00
|
|
|
pub struct EntryHeader {
|
|
|
|
toml: Table,
|
|
|
|
}
|
|
|
|
|
2016-01-18 13:12:12 +00:00
|
|
|
pub type Result<V> = RResult<V, error::ParserError>;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wrapper type around file header (TOML) object
|
|
|
|
*/
|
2016-01-12 17:50:57 +00:00
|
|
|
impl EntryHeader {
|
|
|
|
|
2016-01-21 20:28:18 +00:00
|
|
|
/**
|
|
|
|
* Get a new header object with a already-filled toml table
|
|
|
|
*/
|
2016-01-12 17:50:57 +00:00
|
|
|
pub fn new(toml: Table) -> EntryHeader {
|
|
|
|
EntryHeader {
|
|
|
|
toml: toml,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-21 20:28:18 +00:00
|
|
|
/**
|
|
|
|
* Get the table which lives in the background
|
|
|
|
*/
|
2016-01-12 17:50:57 +00:00
|
|
|
pub fn toml(&self) -> &Table {
|
|
|
|
&self.toml
|
|
|
|
}
|
|
|
|
|
2016-01-18 13:12:12 +00:00
|
|
|
pub fn parse(s: &str) -> Result<EntryHeader> {
|
|
|
|
use toml::Parser;
|
|
|
|
|
|
|
|
let mut parser = Parser::new(s);
|
|
|
|
parser.parse()
|
|
|
|
.ok_or(ParserError::new(ParserErrorKind::TOMLParserErrors, None))
|
2016-01-18 13:56:37 +00:00
|
|
|
.and_then(|table| {
|
|
|
|
if !has_main_section(&table) {
|
|
|
|
Err(ParserError::new(ParserErrorKind::MissingMainSection, None))
|
|
|
|
} else if !has_imag_version_in_main_section(&table) {
|
|
|
|
Err(ParserError::new(ParserErrorKind::MissingVersionInfo, None))
|
|
|
|
} else {
|
|
|
|
Ok(table)
|
|
|
|
}
|
|
|
|
})
|
2016-01-18 13:12:12 +00:00
|
|
|
.map(|table| EntryHeader::new(table))
|
|
|
|
}
|
|
|
|
|
2016-01-12 17:50:57 +00:00
|
|
|
}
|
2016-01-18 13:56:37 +00:00
|
|
|
|
|
|
|
fn has_main_section(t: &Table) -> bool {
|
|
|
|
t.contains_key("imag") &&
|
|
|
|
match t.get("imag") {
|
|
|
|
Some(&Value::Table(_)) => true,
|
|
|
|
Some(_) => false,
|
|
|
|
None => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn has_imag_version_in_main_section(t: &Table) -> bool {
|
|
|
|
match t.get("imag").unwrap() {
|
|
|
|
&Value::Table(ref sec) => {
|
|
|
|
sec.get("version")
|
|
|
|
.and_then(|v| {
|
|
|
|
match v {
|
|
|
|
&Value::String(_) => Some(true),
|
|
|
|
_ => Some(false),
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.unwrap_or(false)
|
|
|
|
}
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|