diff --git a/src/models.py b/src/models.py new file mode 100644 index 0000000..dec861e --- /dev/null +++ b/src/models.py @@ -0,0 +1,81 @@ +"""Data models for Code Pattern Search CLI.""" + +from dataclasses import dataclass, field +from typing import Optional + + +@dataclass +class MatchLocation: + """Represents a location where a pattern matched.""" + + file_path: str + line_number: int + line_content: str + match_start: int + match_end: int + + def to_dict(self) -> dict: + """Convert to dictionary.""" + return { + "file_path": self.file_path, + "line_number": self.line_number, + "line_content": self.line_content, + "match_start": self.match_start, + "match_end": self.match_end, + } + + +@dataclass +class SearchResult: + """Represents search results from a single repository.""" + + repo_name: str + repo_url: str + stars: int + description: Optional[str] = None + language: Optional[str] = None + matches: list[MatchLocation] = field(default_factory=list) + total_matches: int = 0 + score: float = 0.0 + + def to_dict(self) -> dict: + """Convert to dictionary.""" + return { + "repo_name": self.repo_name, + "repo_url": self.repo_url, + "stars": self.stars, + "description": self.description, + "language": self.language, + "matches": [m.to_dict() for m in self.matches], + "total_matches": self.total_matches, + "score": self.score, + } + + def get_match_summary(self) -> dict[str, int]: + """Get a summary of matches grouped by file.""" + summary: dict[str, int] = {} + for match in self.matches: + summary[match.file_path] = summary.get(match.file_path, 0) + 1 + return summary + + +@dataclass +class ExportConfig: + """Configuration for export options.""" + + format: str = "json" + include_metadata: bool = True + pretty_print: bool = True + + +@dataclass +class SearchConfig: + """Configuration for search options.""" + + pattern: str + language: Optional[str] = None + stars_min: int = 0 + stars_max: Optional[int] = None + max_repos: int = 10 + use_cache: bool = True + preset: Optional[str] = None