summaryrefslogtreecommitdiff
path: root/src/bindings.rs
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2020-09-26 09:59:39 +0300
committerLars Wirzenius <liw@liw.fi>2020-09-26 17:54:28 +0300
commit7a9c629cd851d24002529aa721addd3c20a0bf95 (patch)
tree88b51fd1c6713c25c43822a8974c2ad68448202e /src/bindings.rs
parentd987595f007a4d081beb1e5740868051f5d4b56c (diff)
downloadsubplot-7a9c629cd851d24002529aa721addd3c20a0bf95.tar.gz
add: simple word pattern kinds
Diffstat (limited to 'src/bindings.rs')
-rw-r--r--src/bindings.rs116
1 files changed, 112 insertions, 4 deletions
diff --git a/src/bindings.rs b/src/bindings.rs
index 9d80394..56936c0 100644
--- a/src/bindings.rs
+++ b/src/bindings.rs
@@ -7,6 +7,7 @@ use crate::{Result, SubplotError};
use serde::Deserialize;
use serde_aux::prelude::*;
+use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
use std::path::Path;
@@ -595,6 +596,19 @@ mod test_bindings {
}
fn regex_from_simple_pattern(pattern: &str, explicit_plain: bool) -> Result<String> {
+ let kinds = vec![
+ ("word", r"\S+"),
+ ("text", r".*"),
+ ("int", r"-?\d+"),
+ ("uint", r"\d+"),
+ ("number", r"-?\d+(\.\d+)?"),
+ ];
+ let mut regexes: HashMap<String, Regex> = HashMap::new();
+ for (k, v) in kinds.iter() {
+ let r = Regex::new(&v).unwrap();
+ regexes.insert(k.to_string(), r);
+ }
+
let pat = Regex::new(r"\{[^\s\{\}]+\}").unwrap();
let mut r = String::new();
let mut end = 0;
@@ -610,7 +624,20 @@ fn regex_from_simple_pattern(pattern: &str, explicit_plain: bool) -> Result<Stri
}
r.push_str(&escape(before));
let name = &pattern[m.start() + 1..m.end() - 1];
- r.push_str(&format!(r"(?P<{}>\S+)", name));
+
+ let (name, kind) = if let Some(i) = name.find(':') {
+ let (name, suffix) = name.split_at(i);
+ assert!(suffix.starts_with(':'));
+ (name, &suffix[1..])
+ } else {
+ (name, "word")
+ };
+
+ if let Some(regex) = regexes.get(kind) {
+ r.push_str(&format!(r"(?P<{}>{})", name, regex));
+ } else {
+ return Err(SubplotError::UnknownSimplePatternKind(kind.to_string()));
+ }
end = m.end();
}
let after = &pattern[end..];
@@ -630,6 +657,7 @@ fn regex_from_simple_pattern(pattern: &str, explicit_plain: bool) -> Result<Stri
mod test_regex_from_simple_pattern {
use super::regex_from_simple_pattern;
use crate::SubplotError;
+ use regex::Regex;
#[test]
fn returns_empty_string_as_is() {
@@ -649,10 +677,90 @@ mod test_regex_from_simple_pattern {
assert_eq!(ret, r"\.\[\]\*\\\\");
}
+ fn matches(pattern: &str, text: &str) {
+ let r = regex_from_simple_pattern(pattern, false).unwrap();
+ let r = Regex::new(&r).unwrap();
+ let m = r.find(text);
+ assert!(m.is_some());
+ let m = m.unwrap();
+ assert_eq!(m.start(), 0);
+ assert_eq!(m.end(), text.len());
+ }
+
+ fn doesnt_match(pattern: &str, text: &str) {
+ let r = regex_from_simple_pattern(pattern, false).unwrap();
+ let r = Regex::new(&r).unwrap();
+ if let Some(m) = r.find(text) {
+ assert!(m.start() > 0 || m.end() < text.len());
+ }
+ }
+
+ #[test]
+ fn kindless_simple_pattern() {
+ let pattern = "{name}";
+ matches(pattern, "Tomjon");
+ doesnt_match(pattern, "Tomjon of Lancre");
+ }
+
+ #[test]
+ fn simple_word_pattern() {
+ let pattern = "{name:word}";
+ matches(pattern, "Tomjon");
+ doesnt_match(pattern, "Tomjon of Lancre");
+ }
+
+ #[test]
+ fn simple_text_pattern() {
+ let pattern = "{name:text}";
+ matches(pattern, "Tomjon");
+ matches(pattern, "");
+ matches(pattern, "Tomjon of Lancre");
+ }
+
+ #[test]
+ fn simple_int_pattern() {
+ let pattern = "{foo:int}";
+ matches(pattern, "0");
+ matches(pattern, "-0");
+ matches(pattern, "1");
+ matches(pattern, "-1");
+ matches(pattern, "1234");
+ matches(pattern, "-1234");
+ doesnt_match(pattern, " ");
+ doesnt_match(pattern, "one ");
+ doesnt_match(pattern, "1.2 ");
+ doesnt_match(pattern, "-1.2 ");
+ }
+
+ #[test]
+ fn simple_uint_pattern() {
+ let pattern = "{foo:uint}";
+ matches(pattern, "0");
+ matches(pattern, "1");
+ matches(pattern, "1234");
+ doesnt_match(pattern, "-0");
+ doesnt_match(pattern, "-1 ");
+ doesnt_match(pattern, "-1234");
+ doesnt_match(pattern, " ");
+ doesnt_match(pattern, "one ");
+ doesnt_match(pattern, "1.2 ");
+ doesnt_match(pattern, "-1.2 ");
+ }
+
#[test]
- fn returns_simple_pattern_expressed_as_regexp() {
- let ret = regex_from_simple_pattern("I am {name}", false).unwrap();
- assert_eq!(ret, r"I am (?P<name>\S+)");
+ fn simple_number_pattern() {
+ let pattern = "{foo:number}";
+ matches(pattern, "0");
+ matches(pattern, "-0");
+ matches(pattern, "1");
+ matches(pattern, "-1");
+ matches(pattern, "1234");
+ matches(pattern, "-1234");
+ matches(pattern, "1.2");
+ matches(pattern, "-1.2");
+ doesnt_match(pattern, "");
+ doesnt_match(pattern, " ");
+ doesnt_match(pattern, "one");
}
#[test]