Files
docgen-cli/src/docgen/detectors/rust.py
7000pctAUTO a130a2303a
Some checks failed
CI / test (push) Has been cancelled
fix: resolve CI linting violations
- Fixed import sorting in cli.py, __main__.py, detectors/__init__.py, base.py, python.py, rust.py, openapi.py, models/__init__.py
- Removed unused imports (sys, asyncio, Observer, Text, Parameter, ParameterIn, HTTPMethod, DocConfig, List, Optional)
- Removed trailing whitespace from blank lines
- Split lines exceeding 100 characters
- Added missing __init__ docstrings in generators and static/templates packages
2026-01-31 17:26:17 +00:00

92 lines
2.8 KiB
Python

{"""Rust endpoint detector for Actix-web."""
import re
from pathlib import Path
from docgen.detectors.base import BaseDetector
from docgen.models import Endpoint, HTTPMethod
class RustDetector(BaseDetector):
"""Detector for Rust web frameworks."""
extensions = [".rs"]
framework_name = "rust"
ACTIX_PATTERN = re.compile(
r'(?:route|service)\.("|\')(GET|POST|PUT|PATCH|DELETE|OPTIONS|HEAD)("|\')\s*\.?\s*(to|handler)',
re.MULTILINE,
)
ACTIX_WEB_PATTERN = re.compile(
r'(?:App::new\(\)|scope|service)\.route\s*\(\s*"([^"]+)"\s*,\s*([a-zA-Z_][a-zA-Z0-9_]*)',
re.MULTILINE,
)
ACTIX_MACRO_PATTERN = re.compile(
r'#\[route\s*\(\s*"([^"]+)"\s*,\s*method\s*=\s*(?:HttpMethod::)?(GET|POST|PUT|PATCH|DELETE|OPTIONS|HEAD)',
re.MULTILINE,
)
HTTP_METHODS = {"GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"}
METHOD_MAP = {
"GET": HTTPMethod.GET,
"POST": HTTPMethod.POST,
"PUT": HTTPMethod.PUT,
"PATCH": HTTPMethod.PATCH,
"DELETE": HTTPMethod.DELETE,
"OPTIONS": HTTPMethod.OPTIONS,
"HEAD": HTTPMethod.HEAD,
}
def detect_endpoints(self, file_path: Path) -> list[Endpoint]:
"""Detect endpoints in a Rust file."""
content = file_path.read_text()
endpoints = []
if self._detect_actix(content):
endpoints.extend(self._detect_actix_endpoints(content, file_path))
return endpoints
def _detect_actix(self, content: str) -> bool:
"""Check if file uses Actix-web."""
indicators = [
'actix_web',
'actix-web',
'actix::',
'HttpResponse',
'web::Resource',
]
return any(indicator in content for indicator in indicators)
def _detect_actix_endpoints(self, content: str, file_path: Path) -> list[Endpoint]:
"""Detect Actix-web endpoints."""
endpoints = []
for match in self.ACTIX_WEB_PATTERN.finditer(content):
path, handler = match.groups()
endpoint = Endpoint(
path=path,
method=HTTPMethod.GET,
summary=f"GET {path}",
description=f"Handler: {handler}",
file_path=str(file_path),
line_number=content[:match.start()].count("\n") + 1,
)
endpoints.append(endpoint)
for match in self.ACTIX_MACRO_PATTERN.finditer(content):
path, method = match.groups()
endpoint = Endpoint(
path=path,
method=self.METHOD_MAP.get(method, HTTPMethod.GET),
summary=f"{method} {path}",
file_path=str(file_path),
line_number=content[:match.start()].count("\n") + 1,
)
endpoints.append(endpoint)
return endpoints