1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
use pyo3::prelude::*;

/// Represents a compiled regex pattern
pub struct RegexLocal {
    pattern: String,
}

impl RegexLocal {
    /// Creates a new Regex instance
    pub fn new(pattern: &str) -> Self {
        RegexLocal {
            pattern: pattern.to_string(),
        }
    }

    /// Checks if the pattern matches the text
    pub fn is_match(&self, text: &str) -> bool {
        self.match_here(&self.pattern, text)
    }

    /// Matches the pattern here
    fn match_here(&self, pattern: &str, text: &str) -> bool {
        if pattern.is_empty() {
            return true;
        }
        if pattern.len() > 1 && &pattern[1..2] == "*" {
            return self.match_star(&pattern[0..1], &pattern[2..], text);
        }
        if !text.is_empty() && (&pattern[0..1] == "." || pattern[0..1] == text[0..1]) {
            return self.match_here(&pattern[1..], &text[1..]);
        }
        false
    }

    /// Matches zero or more of the preceding element
    fn match_star(&self, char: &str, pattern: &str, text: &str) -> bool {
        let mut text_iter = text.chars();
        while let Some(c) = text_iter.next() {
            if self.match_here(pattern, &text[text_iter.as_str().len()..]) {
                return true;
            }
            if char != "." && char != &c.to_string() {
                return false;
            }
        }
        self.match_here(pattern, "")
    }
}

#[pyclass]
/// A compiled regular expression object
pub struct Regex {
    inner: RegexLocal,
}

#[pymethods]
impl Regex {
    #[new]
    /// Compile a regex pattern
    ///
    /// Args:
    ///     pattern (str): The regex pattern to compile
    ///
    /// Returns:
    ///     Regex: A compiled regex object
    fn new(pattern: &str) -> Self {
        Regex {
            inner: RegexLocal::new(pattern),
        }
    }

    /// Check if the regex pattern matches the text
    ///
    /// Args:
    ///     text (str): The text to match against
    ///
    /// Returns:
    ///     bool: True if the text matches the pattern, False otherwise
    fn is_match(&self, text: &str) -> bool {
        self.inner.is_match(text)
    }
}