litepattern/
lib.rs

1/*
2    litepattern.
3    Lightweight pattern matching library for Rust.
4
5    Copyright (c) 2017 Sam Saint-Pettersen.
6
7    Released under the MIT License.
8*/
9
10//! Light pattern matching library for Rust.
11
12pub struct LPattern {
13    length: usize,
14    groups: Vec<String>,
15}
16
17impl LPattern {
18
19    /// 
20    /// Create a new pattern.
21    /// E.g. %dddd-%dd-%dd
22    ///
23    /// * `pattern` - Pattern to create.
24    ///
25    /// # Return value:
26    /// An LPattern.
27    pub fn new(pattern: &str) -> LPattern {
28        let split = pattern.split("%");
29        let mut groups: Vec<String> = Vec::new();
30        for s in split {
31            if s.to_owned().len() > 0 {
32                groups.push(s.to_owned())
33            }
34        }
35        LPattern {
36            length: groups.join("").len(),
37            groups: groups,
38        }
39    }
40    
41    ///
42    /// Apply the created pattern to some text.
43    /// E.g. 2010-10-10 
44    ///
45    /// * `text` - Text to apply pattern to.
46    ///
47    /// # Return value:
48    /// Vector of pattern matched strings.
49    pub fn apply_to(&self, text: &str) -> Vec<String> {
50        let mut i = 0;
51        let mut captures: Vec<String> = Vec::new();
52        for g in &self.groups {
53            let mut substring: Vec<String> = Vec::new();
54            for _ in 0..g.len() {
55                if i < text.len() {
56                    substring.push(format!("{}", text.chars().nth(i).unwrap()));
57                }
58                i += 1;
59            }
60            captures.push(substring.join(""));
61        }
62        captures
63    }
64    
65    ///
66    /// Determine if the pattern matches from the capture results and text.
67    ///
68    /// * `captures` - Captures returned from apply_to method.
69    /// * `text` - Text to apply pattern to.
70    ///
71    /// # Return value:
72    /// Did the pattern match against capture results and text?
73    pub fn is_match(&self, captures: Vec<String>, text: &str) -> bool {
74        let mut matched = false;
75        let capturesj = captures.join("");
76        if text.len() == self.length {
77            matched = true;
78            for (i, c) in text.chars().enumerate() {
79                if c != capturesj.chars().nth(i).unwrap() {
80                    matched = false;
81                    break;
82                }
83            }
84        }
85        matched
86    }
87}
88
89#[cfg(test)]
90#[test]
91fn test_matching_pattern() {
92    let t = "2010-10-10";
93    let p = LPattern::new("%dddd-%dd-%dd");
94    let caps = p.apply_to(&t);
95    assert_eq!(p.is_match(caps, &t), true);
96}
97
98#[test]
99fn test_failing_pattern() {
100    let t = "spaghetti";
101    let p = LPattern::new("%dddd-%dd-%dd");
102    let caps = p.apply_to(&t);
103    assert_eq!(p.is_match(caps, &t), false);
104}