Extract functions, structs, enums, traits, impl methods, and use declarations from a .rs file.
(path: Path)
| 8774 | }) |
| 8775 | |
| 8776 | def extract_rust(path: Path) -> dict: |
| 8777 | """Extract functions, structs, enums, traits, impl methods, and use declarations from a .rs file.""" |
| 8778 | try: |
| 8779 | import tree_sitter_rust as tsrust |
| 8780 | from tree_sitter import Language, Parser |
| 8781 | except ImportError: |
| 8782 | return {"nodes": [], "edges": [], "error": "tree-sitter-rust not installed"} |
| 8783 | |
| 8784 | try: |
| 8785 | language = Language(tsrust.language()) |
| 8786 | parser = Parser(language) |
| 8787 | source = path.read_bytes() |
| 8788 | tree = parser.parse(source) |
| 8789 | root = tree.root_node |
| 8790 | except Exception as e: |
| 8791 | return {"nodes": [], "edges": [], "error": str(e)} |
| 8792 | |
| 8793 | stem = _file_stem(path) |
| 8794 | str_path = str(path) |
| 8795 | nodes: list[dict] = [] |
| 8796 | edges: list[dict] = [] |
| 8797 | seen_ids: set[str] = set() |
| 8798 | function_bodies: list[tuple[str, object]] = [] |
| 8799 | |
| 8800 | def add_node(nid: str, label: str, line: int) -> None: |
| 8801 | if nid not in seen_ids: |
| 8802 | seen_ids.add(nid) |
| 8803 | nodes.append({ |
| 8804 | "id": nid, |
| 8805 | "label": label, |
| 8806 | "file_type": "code", |
| 8807 | "source_file": str_path, |
| 8808 | "source_location": f"L{line}", |
| 8809 | }) |
| 8810 | |
| 8811 | def add_edge(src: str, tgt: str, relation: str, line: int, |
| 8812 | confidence: str = "EXTRACTED", weight: float = 1.0, |
| 8813 | context: str | None = None) -> None: |
| 8814 | edge = { |
| 8815 | "source": src, |
| 8816 | "target": tgt, |
| 8817 | "relation": relation, |
| 8818 | "confidence": confidence, |
| 8819 | "source_file": str_path, |
| 8820 | "source_location": f"L{line}", |
| 8821 | "weight": weight, |
| 8822 | } |
| 8823 | if context: |
| 8824 | edge["context"] = context |
| 8825 | edges.append(edge) |
| 8826 | |
| 8827 | file_nid = _make_id(str(path)) |
| 8828 | add_node(file_nid, path.name, 1) |
| 8829 | |
| 8830 | def ensure_named_node(name: str, line: int) -> str: |
| 8831 | nid = _make_id(stem, name) |
| 8832 | if nid in seen_ids: |
| 8833 | return nid |