From 589844102da75293b840fb184912a1c7e8d9d20a Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 30 Oct 2015 14:44:41 +0100 Subject: [PATCH] Move parser code out of file.rs --- src/storage/file.rs | 125 ----------------------------------------- src/storage/mod.rs | 1 + src/storage/parser.rs | 128 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+), 125 deletions(-) create mode 100644 src/storage/parser.rs diff --git a/src/storage/file.rs b/src/storage/file.rs index 1766dbf2..3007f6d3 100644 --- a/src/storage/file.rs +++ b/src/storage/file.rs @@ -1,32 +1,3 @@ -use regex::Regex; - -pub struct ParserError { - summary: String, - parsertext: String, - index: i32, - explanation: Option, -} - -impl ParserError { - fn new(sum: &'static str, text: String, idx: i32, expl: &'static str) -> ParserError { - ParserError { - summary: String::from(sum), - parsertext: text, - index: idx, - explanation: Some(String::from(expl)), - } - } - - fn short(sum: &'static str, text: String, idx: i32) -> ParserError { - ParserError { - summary: String::from(sum), - parsertext: text, - index: idx, - explanation: None - } - } -} - pub enum FileHeaderSpec { Null, Bool, @@ -49,104 +20,8 @@ pub enum FileHeaderData { Array { values: Box> }, } -pub trait FileHeaderParser : Sized { - fn new(spec: &FileHeaderSpec) -> Self; - fn read(&self, string: Option) -> Result; - fn write(&self, data: &FileHeaderData) -> Result; -} - pub trait FileData : Sized { fn get_fulltext(&self) -> String; fn get_abbrev(&self) -> String; } -pub trait FileDataParser : Sized { - fn new() -> Self; - fn read(&self, string: Option) -> Result; - fn write(&self, data: &FD) -> Result; -} - -type TextTpl = (Option, Option); - -pub struct Parser -{ - headerp : HP, - datap : DP, -} - -impl Parser where - HP: FileHeaderParser, -{ - - fn new(headerp: HP, datap: DP) -> Parser { - Parser { - headerp: headerp, - datap: datap, - } - } - - fn read(&self, s: String) -> Result<(FileHeaderData, FD), ParserError> - where FD: FileData + Sized, - DP: FileDataParser - { - let divided = divide_text(&s); - - if divided.is_err() { - return Err(divided.err().unwrap()); - } - - let (header, data) = divided.ok().unwrap(); - - let h_parseres = self.headerp.read(header); - let d_parseres = self.datap.read(data); - - if h_parseres.is_err() { - return Err(h_parseres.err().unwrap()); - } - - if d_parseres.is_err() { - return Err(d_parseres.err().unwrap()); - } - - Ok((h_parseres.ok().unwrap(), d_parseres.ok().unwrap())) - } - - fn write(&self, tpl : (FileHeaderData, FD)) -> Result - where FD: FileData + Sized, - DP: FileDataParser - { - let (header, data) = tpl; - let h_text = self.headerp.write(&header); - let d_text = self.datap.write(&data); - - if h_text.is_err() { - return Err(h_text.err().unwrap()); - } - - if d_text.is_err() { - return Err(d_text.err().unwrap()); - } - - Ok(h_text.ok().unwrap() + &d_text.ok().unwrap()[..]) - } -} - -fn divide_text(text: &String) -> Result { - let re = Regex::new(r"(?m)^\-\-\-$\n(.*)^\-\-\-$\n(.*)").unwrap(); - - let captures = re.captures(&text[..]).unwrap_or( - return Err(ParserError::new("Cannot run regex on text", - text.clone(), 0, - "Cannot run regex on text to divide it into header and content.")) - ); - - if captures.len() != 2 { - return Err(ParserError::new("Unexpected Regex output", - text.clone(), 0, - "The regex to divide text into header and content had an unexpected output.")) - } - - let header = captures.at(0).map(|s| String::from(s)); - let content = captures.at(1).map(|s| String::from(s)); - Ok((header, content)) -} diff --git a/src/storage/mod.rs b/src/storage/mod.rs index 28267aad..403c8369 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -5,6 +5,7 @@ pub use std::error::Error; pub use runtime::Runtime; mod file; +mod parser; pub trait StorageBackend { diff --git a/src/storage/parser.rs b/src/storage/parser.rs new file mode 100644 index 00000000..4a345636 --- /dev/null +++ b/src/storage/parser.rs @@ -0,0 +1,128 @@ +use regex::Regex; + +use super::file::*; + +pub struct ParserError { + summary: String, + parsertext: String, + index: i32, + explanation: Option, +} + +impl ParserError { + fn new(sum: &'static str, text: String, idx: i32, expl: &'static str) -> ParserError { + ParserError { + summary: String::from(sum), + parsertext: text, + index: idx, + explanation: Some(String::from(expl)), + } + } + + fn short(sum: &'static str, text: String, idx: i32) -> ParserError { + ParserError { + summary: String::from(sum), + parsertext: text, + index: idx, + explanation: None + } + } +} + +pub trait FileHeaderParser : Sized { + fn new(spec: &FileHeaderSpec) -> Self; + fn read(&self, string: Option) -> Result; + fn write(&self, data: &FileHeaderData) -> Result; +} + +pub trait FileDataParser : Sized { + fn new() -> Self; + fn read(&self, string: Option) -> Result; + fn write(&self, data: &FD) -> Result; +} + +type TextTpl = (Option, Option); + +pub struct Parser +{ + headerp : HP, + datap : DP, +} + +impl Parser where + HP: FileHeaderParser, +{ + + fn new(headerp: HP, datap: DP) -> Parser { + Parser { + headerp: headerp, + datap: datap, + } + } + + fn read(&self, s: String) -> Result<(FileHeaderData, FD), ParserError> + where FD: FileData + Sized, + DP: FileDataParser + { + let divided = divide_text(&s); + + if divided.is_err() { + return Err(divided.err().unwrap()); + } + + let (header, data) = divided.ok().unwrap(); + + let h_parseres = self.headerp.read(header); + let d_parseres = self.datap.read(data); + + if h_parseres.is_err() { + return Err(h_parseres.err().unwrap()); + } + + if d_parseres.is_err() { + return Err(d_parseres.err().unwrap()); + } + + Ok((h_parseres.ok().unwrap(), d_parseres.ok().unwrap())) + } + + fn write(&self, tpl : (FileHeaderData, FD)) -> Result + where FD: FileData + Sized, + DP: FileDataParser + { + let (header, data) = tpl; + let h_text = self.headerp.write(&header); + let d_text = self.datap.write(&data); + + if h_text.is_err() { + return Err(h_text.err().unwrap()); + } + + if d_text.is_err() { + return Err(d_text.err().unwrap()); + } + + Ok(h_text.ok().unwrap() + &d_text.ok().unwrap()[..]) + } +} + +fn divide_text(text: &String) -> Result { + let re = Regex::new(r"(?m)^\-\-\-$\n(.*)^\-\-\-$\n(.*)").unwrap(); + + let captures = re.captures(&text[..]).unwrap_or( + return Err(ParserError::new("Cannot run regex on text", + text.clone(), 0, + "Cannot run regex on text to divide it into header and content.")) + ); + + if captures.len() != 2 { + return Err(ParserError::new("Unexpected Regex output", + text.clone(), 0, + "The regex to divide text into header and content had an unexpected output.")) + } + + let header = captures.at(0).map(|s| String::from(s)); + let content = captures.at(1).map(|s| String::from(s)); + Ok((header, content)) +} +