From e6fb2f232d62e36ee9f94e73fdc60d41eb6a5f9d Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 30 Oct 2015 16:47:04 +0100 Subject: [PATCH 1/6] FileHeaderSpec, FileHeaderData can derive Debug --- src/storage/file.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/storage/file.rs b/src/storage/file.rs index 3007f6d3..b58486cc 100644 --- a/src/storage/file.rs +++ b/src/storage/file.rs @@ -1,3 +1,4 @@ +#[derive(Debug)] pub enum FileHeaderSpec { Null, Bool, @@ -9,6 +10,7 @@ pub enum FileHeaderSpec { Array { allowed_types: Box> }, } +#[derive(Debug)] pub enum FileHeaderData { Null, Bool(bool), From 96ca9637d1e2d2be3f98baa2751494767ccdb070 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 30 Oct 2015 16:48:48 +0100 Subject: [PATCH 2/6] Add type MatchError --- src/storage/file.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/storage/file.rs b/src/storage/file.rs index b58486cc..72d7a83a 100644 --- a/src/storage/file.rs +++ b/src/storage/file.rs @@ -1,3 +1,7 @@ +use std::error::Error; +use std::fmt::{Debug, Display, Formatter}; +use std::fmt; + #[derive(Debug)] pub enum FileHeaderSpec { Null, @@ -27,3 +31,47 @@ pub trait FileData : Sized { fn get_abbrev(&self) -> String; } +pub struct MatchError { + summary: String, + path: Vec, + expected: FileHeaderSpec, + found: FileHeaderSpec +} + +impl MatchError { + pub fn format(&self) -> String { + format!("MatchError: {:?}\n\nHaving: {:?}\nExpected: {:?}\nFound: {:?}\n", + self.summary, self.path, self.expected, self.found) + } +} + +impl Error for MatchError { + + fn description(&self) -> &str { + &self.summary[..] + } + + fn cause(&self) -> Option<&Error> { + None + } + +} + +impl Debug for MatchError { + + fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { + write!(fmt, "{}", self.format()); + Ok(()) + } + +} + +impl Display for MatchError { + + fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { + write!(fmt, "{}", self.format()); + Ok(()) + } + +} + From f9cc0e41ce691e110bc25fc0ee9b188296260b63 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 30 Oct 2015 16:50:02 +0100 Subject: [PATCH 3/6] Implement Display for FileHeaderSpec --- src/storage/file.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/storage/file.rs b/src/storage/file.rs index 72d7a83a..bc1c57c9 100644 --- a/src/storage/file.rs +++ b/src/storage/file.rs @@ -31,6 +31,27 @@ pub trait FileData : Sized { fn get_abbrev(&self) -> String; } +impl Display for FileHeaderSpec { + + fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { + match self { + &FileHeaderSpec::Null => write!(fmt, "NULL"), + &FileHeaderSpec::Bool => write!(fmt, "Bool"), + &FileHeaderSpec::Integer => write!(fmt, "Integer"), + &FileHeaderSpec::UInteger => write!(fmt, "UInteger"), + &FileHeaderSpec::Float => write!(fmt, "Float"), + &FileHeaderSpec::Text => write!(fmt, "Text"), + &FileHeaderSpec::Key{name: ref n, value_type: ref vt} => { + write!(fmt, "Key({:?}) -> {:?}", n, vt) + } + &FileHeaderSpec::Array{allowed_types: ref at} => { + write!(fmt, "Array({:?})", at) + } + } + } + +} + pub struct MatchError { summary: String, path: Vec, From caee02c33300bbb5bedf560d37ff99fdd0276cfb Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 30 Oct 2015 16:50:43 +0100 Subject: [PATCH 4/6] Add algorithm to match spec on data --- src/storage/file.rs | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/storage/file.rs b/src/storage/file.rs index bc1c57c9..302105c0 100644 --- a/src/storage/file.rs +++ b/src/storage/file.rs @@ -96,3 +96,42 @@ impl Display for MatchError { } +pub fn match_header_spec(spec: &FileHeaderSpec, data: &FileHeaderData) + -> Option +{ + let tpl = (spec, data); + match tpl { + (&FileHeaderSpec::Null, &FileHeaderData::Null) => { } + (&FileHeaderSpec::Bool, &FileHeaderData::Bool(_)) => { } + (&FileHeaderSpec::Integer, &FileHeaderData::Integer(_)) => { } + (&FileHeaderSpec::UInteger, &FileHeaderData::UInteger(_)) => { } + (&FileHeaderSpec::Float, &FileHeaderData::Float(_)) => { } + (&FileHeaderSpec::Text, &FileHeaderData::Text(_)) => { } + + ( + &FileHeaderSpec::Key{name: ref kname, value_type: ref vtype}, + &FileHeaderData::Key{name: ref n, value: ref val} + ) => { + if kname != n { + // error + } + return match_header_spec(&*vtype, &*val); + } + + ( + &FileHeaderSpec::Array{allowed_types: ref vtypes}, + &FileHeaderData::Array{values: ref vs} + ) => { + for (t, v) in vtypes.iter().zip(vs.iter()) { + let res = match_header_spec(t, v); + if res.is_some() { + return res; + } + } + } + + _ => { unreachable!() } + } + None +} + From 10697feb8aba9e5af0821ea397939ee713acde23 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 30 Oct 2015 17:35:18 +0100 Subject: [PATCH 5/6] Add error generating Which required adding of lifetimes --- src/storage/file.rs | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/src/storage/file.rs b/src/storage/file.rs index 302105c0..f37081b8 100644 --- a/src/storage/file.rs +++ b/src/storage/file.rs @@ -52,21 +52,34 @@ impl Display for FileHeaderSpec { } -pub struct MatchError { +pub struct MatchError<'a> { summary: String, path: Vec, - expected: FileHeaderSpec, - found: FileHeaderSpec + expected: &'a FileHeaderSpec, + found: &'a FileHeaderData } -impl MatchError { +impl<'a> MatchError<'a> { + + pub fn new(s: String, + path: Vec, + ex: &'a FileHeaderSpec, + found: &'a FileHeaderData) -> MatchError<'a> { + MatchError { + summary: s, + path: path, + expected: ex, + found: found, + } + } + pub fn format(&self) -> String { format!("MatchError: {:?}\n\nHaving: {:?}\nExpected: {:?}\nFound: {:?}\n", self.summary, self.path, self.expected, self.found) } } -impl Error for MatchError { +impl<'a> Error for MatchError<'a> { fn description(&self) -> &str { &self.summary[..] @@ -78,7 +91,7 @@ impl Error for MatchError { } -impl Debug for MatchError { +impl<'a> Debug for MatchError<'a> { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { write!(fmt, "{}", self.format()); @@ -87,7 +100,7 @@ impl Debug for MatchError { } -impl Display for MatchError { +impl<'a> Display for MatchError<'a> { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { write!(fmt, "{}", self.format()); @@ -96,11 +109,10 @@ impl Display for MatchError { } -pub fn match_header_spec(spec: &FileHeaderSpec, data: &FileHeaderData) - -> Option +pub fn match_header_spec<'a>(spec: &'a FileHeaderSpec, data: &'a FileHeaderData) + -> Option> { - let tpl = (spec, data); - match tpl { + match (spec, data) { (&FileHeaderSpec::Null, &FileHeaderData::Null) => { } (&FileHeaderSpec::Bool, &FileHeaderData::Bool(_)) => { } (&FileHeaderSpec::Integer, &FileHeaderData::Integer(_)) => { } @@ -130,7 +142,12 @@ pub fn match_header_spec(spec: &FileHeaderSpec, data: &FileHeaderData) } } - _ => { unreachable!() } + (k, v) => { + return Some(MatchError::new(String::from("Expected type does not match found type"), + vec![], + k, v + )) + } } None } From 9dde3e4f72b9ef3371a5997802fbb9180652b04f Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 30 Oct 2015 17:46:25 +0100 Subject: [PATCH 6/6] Remove path member from MatchError At this point, this is too complicated to implement for me. --- src/storage/file.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/storage/file.rs b/src/storage/file.rs index f37081b8..0d0df446 100644 --- a/src/storage/file.rs +++ b/src/storage/file.rs @@ -54,7 +54,6 @@ impl Display for FileHeaderSpec { pub struct MatchError<'a> { summary: String, - path: Vec, expected: &'a FileHeaderSpec, found: &'a FileHeaderData } @@ -62,20 +61,18 @@ pub struct MatchError<'a> { impl<'a> MatchError<'a> { pub fn new(s: String, - path: Vec, ex: &'a FileHeaderSpec, found: &'a FileHeaderData) -> MatchError<'a> { MatchError { summary: s, - path: path, expected: ex, found: found, } } pub fn format(&self) -> String { - format!("MatchError: {:?}\n\nHaving: {:?}\nExpected: {:?}\nFound: {:?}\n", - self.summary, self.path, self.expected, self.found) + format!("MatchError: {:?}\nExpected: {:?}\nFound: {:?}\n", + self.summary, self.expected, self.found) } } @@ -144,7 +141,6 @@ pub fn match_header_spec<'a>(spec: &'a FileHeaderSpec, data: &'a FileHeaderData) (k, v) => { return Some(MatchError::new(String::from("Expected type does not match found type"), - vec![], k, v )) }