Source code for simulator.utils
from __future__ import annotations
from functools import wraps
from pathlib import Path
from typing import Any, Callable, Dict, Type, TypeVar
import json
T = TypeVar("T")
[docs]
def ensure_dir(path: str | Path) -> None:
p = Path(path)
if p.is_dir():
p.mkdir(parents=True, exist_ok=True)
else:
p.parent.mkdir(parents=True, exist_ok=True)
[docs]
def dataclass_from_dict(cls: Type[T], data: Dict[str, Any]) -> T:
field_names = {f.name for f in getattr(cls, "__dataclass_fields__", {}).values()}
filtered = {k: v for k, v in data.items() if k in field_names}
return cls(**filtered) # type: ignore[arg-type]
[docs]
def load_json(path: str | Path) -> dict:
with open(path, "r", encoding="utf-8") as f:
return json.load(f)
[docs]
def save_json(path: str | Path, data: dict) -> None:
ensure_dir(path)
with open(path, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2)
[docs]
def log_call(func: Callable[..., T]) -> Callable[..., T]:
@wraps(func)
def wrapper(*args: Any, **kwargs: Any) -> T:
name = func.__qualname__
print(f"[simulator] -> {name}")
result = func(*args, **kwargs)
print(f"[simulator] <- {name}")
return result
return wrapper