diff --git a/src/models/rule.py b/src/models/rule.py new file mode 100644 index 0000000..f1d0b66 --- /dev/null +++ b/src/models/rule.py @@ -0,0 +1,61 @@ +"""Rule model for validation patterns.""" + +import re +from dataclasses import dataclass, field +from typing import Optional, Pattern + + +@dataclass +class Rule: + """Represents a validation rule.""" + + id: str + name: str + pattern: str + severity: str + message: str + suggestion: str = "" + enabled: bool = True + _compiled_pattern: Optional[Pattern[str]] = field(default=None, repr=False) + + def __post_init__(self): + """Compile the regex pattern after initialization.""" + try: + self._compiled_pattern = re.compile(self.pattern) + except re.error as e: + raise ValueError(f"Invalid regex pattern '{self.pattern}': {e}") + + def match(self, text: str) -> Optional[re.Match[str]]: + """Match the pattern against text.""" + if self._compiled_pattern: + return self._compiled_pattern.search(text) + return None + + def matches(self, text: str) -> bool: + """Check if the pattern matches the text.""" + return self.match(text) is not None + + def to_dict(self) -> dict: + """Convert rule to dictionary.""" + return { + "id": self.id, + "name": self.name, + "pattern": self.pattern, + "severity": self.severity, + "message": self.message, + "suggestion": self.suggestion, + "enabled": self.enabled, + } + + @classmethod + def from_dict(cls, data: dict) -> "Rule": + """Create a Rule from a dictionary.""" + return cls( + id=data["id"], + name=data["name"], + pattern=data["pattern"], + severity=data["severity"], + message=data["message"], + suggestion=data.get("suggestion", ""), + enabled=data.get("enabled", True), + )