diff options
Diffstat (limited to 'src/barbfile.rs')
-rw-r--r-- | src/barbfile.rs | 98 |
1 files changed, 81 insertions, 17 deletions
diff --git a/src/barbfile.rs b/src/barbfile.rs index 66a8756..35b0224 100644 --- a/src/barbfile.rs +++ b/src/barbfile.rs @@ -1,3 +1,4 @@ +use regex::Regex; use std::str::FromStr; use std::string::ToString; use std::{error::Error, fmt}; @@ -7,6 +8,10 @@ pub struct BarbParseError {} impl Error for BarbParseError {} +trait PreambleLine { + fn is_match(s: String) -> bool; +} + impl fmt::Display for BarbParseError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Error parsing barb file") @@ -80,20 +85,65 @@ impl Header { } } +pub struct BarbFilter { + name: Option<String>, + filter: String, +} + +impl FromStr for BarbFilter { + type Err = BarbParseError; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + let re = Regex::new("^#(?P<name>[A-Za-z0-9_]*)\\|(?P<filter>.+)$").unwrap(); + let groups = re.captures(s).ok_or(BarbParseError {})?; + + Ok(BarbFilter::new( + match &groups["name"] { + "" => None, + any => Some(String::from(any)), + }, + String::from(&groups["filter"]), + )) + } +} + +impl PreambleLine for BarbFilter { + fn is_match(s: String) -> bool { + let re = Regex::new("^#(?P<name>[A-Za-z0-9_]*)\\|(?P<filter>.+)$").unwrap(); + re.is_match(s.as_str()) + } +} + +impl BarbFilter { + pub fn new(name: Option<String>, filter: String) -> BarbFilter { + BarbFilter { name, filter } + } + + pub fn name(&self) -> &Option<String> { + &self.name + } + + pub fn filter(&self) -> &String { + &self.filter + } +} + struct BarbPreamble { pub method: Method, pub url: String, pub headers: Vec<Header>, - pub filter: Option<String>, + pub filters: Vec<BarbFilter>, + //pub filter: Option<BarbFilter>, } impl BarbPreamble { - fn new(method: Method, url: String, headers: Vec<Header>, filter: Option<String>) -> Self { + fn new(method: Method, url: String, headers: Vec<Header>, filters: Vec<BarbFilter>) -> Self { BarbPreamble { - method: method, - url: url, - headers: headers, - filter: filter, + method, + url, + headers, + //filter: Vec<BarbFilter>, + filters, } } } @@ -120,8 +170,8 @@ impl BarbFile { &self.preamble.url } - pub fn filter(&self) -> &Option<String> { - &self.preamble.filter + pub fn filters(&self) -> &Vec<BarbFilter> { + &self.preamble.filters } pub fn body(&self) -> &Option<String> { @@ -153,7 +203,7 @@ impl FromStr for BarbFile { let mut lines = s.split('\n'); let (method, url) = decode_url_line(lines.next().ok_or(BarbParseError {})?)?; let mut headers: Vec<Header> = vec![]; - let mut filter = None; + let mut filters: Vec<BarbFilter> = vec![]; for line in &mut lines { if line == "" { @@ -165,18 +215,18 @@ impl FromStr for BarbFile { headers.push(decode_header(line).map_err(|_| BarbParseError {})?); } - if let None = filter { - filter = match &line[0..2] { - "#|" => Some(String::from(&line[2..])), - _ => None, - } + if BarbFilter::is_match(String::from(line)) { + match BarbFilter::from_str(line) { + Ok(filter) => filters.push(filter), + Err(_) => () + }; } } let body = lines.fold(String::from(""), |acc, x| acc + x); Ok(BarbFile { - preamble: BarbPreamble::new(method, url, headers, filter), + preamble: BarbPreamble::new(method, url, headers, filters), body: if body == "" { None } else { Some(body) }, }) } @@ -220,7 +270,7 @@ mod tests { .unwrap(); assert!(matches!(barbfile.preamble.method, Method::GET)); assert_eq!(barbfile.preamble.url, "https://blah.com/api/blah"); - assert_eq!(barbfile.preamble.filter, Some(String::from("filtr"))); + assert_eq!(barbfile.preamble.filters[0].filter(), &String::from("filtr")); assert_eq!(barbfile.preamble.headers.len(), 1); assert_eq!(barbfile.preamble.headers[0].name, "Authorization"); assert_eq!(barbfile.preamble.headers[0].value, "BLAH"); @@ -234,10 +284,24 @@ mod tests { .unwrap(); assert!(matches!(barbfile.preamble.method, Method::POST)); assert_eq!(barbfile.preamble.url, "https://blah.com/api/blah"); - assert_eq!(barbfile.preamble.filter, Some(String::from("filtr"))); + assert_eq!(barbfile.preamble.filters[0].filter(), &String::from("filtr")); assert_eq!(barbfile.preamble.headers.len(), 1); assert_eq!(barbfile.preamble.headers[0].name, "Authorization"); assert_eq!(barbfile.preamble.headers[0].value, "BLAH"); assert_eq!(barbfile.body, Some(String::from("{\"key\":\"value\"}"))) } + + #[test] + fn test_parse_named_filter() { + let filter = BarbFilter::from_str("#FOO|.bar.foo").unwrap(); + assert_eq!(filter.name, Some(String::from("FOO"))); + assert_eq!(filter.filter, String::from(".bar.foo")); + } + + #[test] + fn test_parse_named_filter_no_name() { + let filter = BarbFilter::from_str("#|.bar.foo").unwrap(); + assert_eq!(filter.name, None); + assert_eq!(filter.filter, String::from(".bar.foo")); + } } |