This commit is contained in:
Till Wegmueller 2020-05-18 10:32:16 +02:00
parent 4ef26a70d2
commit f33df3d0ab
2 changed files with 27 additions and 34 deletions

View file

@ -3,14 +3,13 @@
// MPL was not distributed with this file, You can // MPL was not distributed with this file, You can
// obtain one at https://mozilla.org/MPL/2.0/. // obtain one at https://mozilla.org/MPL/2.0/.
use regex::Regex;
use std::collections::HashSet;
use std::error;
use std::fmt;
use std::fs::File; use std::fs::File;
use std::io::BufRead; use std::io::BufRead;
use std::io::BufReader; use std::io::BufReader;
use std::error;
use std::fmt;
use regex::Regex;
use regex::RegexSet;
use std::collections::HashSet;
pub struct Dir { pub struct Dir {
pub path: String, pub path: String,
@ -37,7 +36,7 @@ pub struct Manifest {
impl Manifest { impl Manifest {
pub fn new() -> Manifest { pub fn new() -> Manifest {
return Manifest{ return Manifest {
attributes: Vec::new(), attributes: Vec::new(),
}; };
} }
@ -67,8 +66,7 @@ pub enum ManifestError {
impl fmt::Display for ManifestError { impl fmt::Display for ManifestError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {
ManifestError::EmptyVec => ManifestError::EmptyVec => write!(f, "please use a vector with at least one element"),
write!(f, "please use a vector with at least one element"),
// This is a wrapper, so defer to the underlying types' implementation of `fmt`. // This is a wrapper, so defer to the underlying types' implementation of `fmt`.
ManifestError::Read(ref e) => e.fmt(f), ManifestError::Read(ref e) => e.fmt(f),
ManifestError::Regex(ref e) => e.fmt(f), ManifestError::Regex(ref e) => e.fmt(f),
@ -96,18 +94,18 @@ pub fn parse_manifest_file(filename: String) -> Result<Manifest, ManifestError>
Err(e) => return Err(ManifestError::Read(e)), Err(e) => return Err(ManifestError::Read(e)),
}; };
let file = BufReader::new(&f); let file = BufReader::new(&f);
for lineRead in file.lines() { for line_read in file.lines() {
let line = match lineRead { let line = match line_read {
Ok(l) => l, Ok(l) => l,
Err(e) => return Err(ManifestError::Read(e)), Err(e) => return Err(ManifestError::Read(e)),
}; };
if is_attr_action(&line) { if is_attr_action(&line) {
match parse_attr_action(line) { match parse_attr_action(line) {
Ok(attr) => manifest.attributes.push(attr), Ok(attr) => manifest.attributes.push(attr),
Err(e) => return Err(e) Err(e) => return Err(e),
} }
} }
} }
return Ok(manifest); return Ok(manifest);
} }
@ -115,13 +113,13 @@ pub fn parse_manifest_string(manifest: String) -> Result<Manifest, ManifestError
let mut m = Manifest::new(); let mut m = Manifest::new();
for line in manifest.lines() { for line in manifest.lines() {
if is_attr_action(&String::from(line)) { if is_attr_action(&String::from(line)) {
let attr = match parse_attr_action(String::from(line)) { match parse_attr_action(String::from(line)) {
Ok(attr) => m.attributes.push(attr), Ok(attr) => m.attributes.push(attr),
Err(e) => return Err(e) Err(e) => return Err(e),
}; };
} }
} }
return Ok(m) return Ok(m);
} }
fn is_attr_action(line: &String) -> bool { fn is_attr_action(line: &String) -> bool {
@ -135,7 +133,7 @@ pub fn parse_attr_action(line: String) -> Result<Attr, ManifestError> {
//Todo move regex initialisation out of for loop into static area //Todo move regex initialisation out of for loop into static area
let name_regex = match Regex::new(r"name=([^ ]+) value=") { let name_regex = match Regex::new(r"name=([^ ]+) value=") {
Ok(re) => re, Ok(re) => re,
Err(e) => return Err(ManifestError::Regex(e)) Err(e) => return Err(ManifestError::Regex(e)),
}; };
let mut key = String::new(); let mut key = String::new();
for cap in name_regex.captures_iter(line.trim_start()) { for cap in name_regex.captures_iter(line.trim_start()) {
@ -156,12 +154,12 @@ pub fn parse_attr_action(line: String) -> Result<Attr, ManifestError> {
let mut properties = HashSet::new(); let mut properties = HashSet::new();
let optionals_regex_no_quotes = match Regex::new(r#"([^ ]+)=([^"][^ ]+[^"])"#) { let optionals_regex_no_quotes = match Regex::new(r#"([^ ]+)=([^"][^ ]+[^"])"#) {
Ok(re) => re, Ok(re) => re,
Err(e) => return Err(ManifestError::Regex(e)) Err(e) => return Err(ManifestError::Regex(e)),
}; };
let optionals_regex_quotes = match Regex::new(r#"([^ ]+)=([^"][^ ]+[^"])"#) { let optionals_regex_quotes = match Regex::new(r#"([^ ]+)=([^"][^ ]+[^"])"#) {
Ok(re) => re, Ok(re) => re,
Err(e) => return Err(ManifestError::Regex(e)) Err(e) => return Err(ManifestError::Regex(e)),
}; };
for cap in value_no_space_regex.captures_iter(line.trim_start()) { for cap in value_no_space_regex.captures_iter(line.trim_start()) {
@ -177,7 +175,7 @@ pub fn parse_attr_action(line: String) -> Result<Attr, ManifestError> {
continue; continue;
} }
properties.insert(Property{ properties.insert(Property {
key: String::from(cap[1].trim()), key: String::from(cap[1].trim()),
value: String::from(cap[2].trim()), value: String::from(cap[2].trim()),
}); });
@ -188,15 +186,15 @@ pub fn parse_attr_action(line: String) -> Result<Attr, ManifestError> {
continue; continue;
} }
properties.insert(Property{ properties.insert(Property {
key: String::from(cap[1].trim()), key: String::from(cap[1].trim()),
value: String::from(cap[2].trim()), value: String::from(cap[2].trim()),
}); });
} }
Ok(Attr{ Ok(Attr {
key, key,
values, values,
properties, properties,
}) })
} }

View file

@ -8,11 +8,8 @@ mod actions;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::actions::{parse_manifest_string, Attr};
use crate::actions::Manifest; use crate::actions::Manifest;
use crate::actions::ManifestError; use crate::actions::{parse_manifest_string, Attr};
use std::error;
use std::fmt;
use std::collections::HashSet; use std::collections::HashSet;
#[test] #[test]
@ -29,7 +26,7 @@ mod tests {
set name=org.opensolaris.consolidation value=userland set name=org.opensolaris.consolidation value=userland
set name=com.oracle.info.version value=1.18.0 set name=com.oracle.info.version value=1.18.0
set name=variant.arch value=i386"); set name=variant.arch value=i386");
let testResults = vec![ let test_results = vec![
Attr{ Attr{
key: String::from("pkg.fmri"), key: String::from("pkg.fmri"),
values: vec![String::from("pkg://openindiana.org/web/server/nginx@1.18.0,5.11-2020.0.1.0:20200421T195136Z")], values: vec![String::from("pkg://openindiana.org/web/server/nginx@1.18.0,5.11-2020.0.1.0:20200421T195136Z")],
@ -92,19 +89,17 @@ mod tests {
} }
]; ];
let mut manifest = Manifest::new(); let mut manifest = Manifest::new();
match parse_manifest_string(manifest_string){ match parse_manifest_string(manifest_string) {
Ok(m) => manifest = m, Ok(m) => manifest = m,
Err(_) => assert!(false, "caught error") Err(_) => assert!(false, "caught error"),
}; };
assert_eq!(manifest.attributes.len(), 12); assert_eq!(manifest.attributes.len(), 12);
for (pos, attr) in manifest.attributes.iter().enumerate() { for (pos, attr) in manifest.attributes.iter().enumerate() {
assert_eq!(attr.key, testResults[pos].key); assert_eq!(attr.key, test_results[pos].key);
for (vpos, val) in attr.values.iter().enumerate() { for (vpos, val) in attr.values.iter().enumerate() {
assert_eq!(val, &testResults[pos].values[vpos]); assert_eq!(val, &test_results[pos].values[vpos]);
} }
} }
} }
} }