"""Shared utility functions.""" from __future__ import annotations import json _JSON_DECODER = json.JSONDecoder() def load_card_database(): """Load the structured card database from data/card_database.json.""" from lexenvs.config import project_root from lexenvs.schemas.card_database import CardDatabase db_path = project_root() / "data" / "card_database.json" if not db_path.exists(): return None db_json = json.loads(db_path.read_text(encoding="utf-8")) return CardDatabase(**db_json) def extract_json_block(text: str) -> dict | None: # type: ignore[type-arg] """Extract the first JSON object from text. Looks for ```json ... ``` fenced blocks first, then scans for the first valid JSON object using the stdlib decoder. """ # Try fenced code block via string splitting marker = "```json" start = text.find(marker) if start != -1: inner_start = text.index("\n", start) + 1 end = text.find("```", inner_start) if end != -1: try: return json.loads(text[inner_start:end]) # type: ignore[no-any-return] except json.JSONDecodeError: pass # Scan for the first raw JSON object using raw_decode decoder = _JSON_DECODER idx = text.find("{") while idx != -1: try: obj, _ = decoder.raw_decode(text, idx) if isinstance(obj, dict): return obj # type: ignore[no-any-return] except json.JSONDecodeError: pass idx = text.find("{", idx + 1) return None