Source code for swcstudio.core.config
"""Feature config JSON helpers.
Each feature keeps a JSON file under:
swcstudio/tools/<tool>/configs/<feature>.json
"""
from __future__ import annotations
import json
from pathlib import Path
from typing import Any
TOOLS_DIR = Path(__file__).resolve().parents[1] / "tools"
def feature_config_path(tool: str, feature: str) -> Path:
return TOOLS_DIR / tool / "configs" / f"{feature}.json"
def load_feature_config(tool: str, feature: str, default: dict | None = None) -> dict[str, Any]:
path = feature_config_path(tool, feature)
if not path.exists():
return dict(default or {})
try:
return json.loads(path.read_text(encoding="utf-8"))
except Exception:
return dict(default or {})
def save_feature_config(tool: str, feature: str, config: dict[str, Any]) -> Path:
path = feature_config_path(tool, feature)
path.parent.mkdir(parents=True, exist_ok=True)
tmp = path.with_suffix(".tmp.json")
tmp.write_text(json.dumps(config, indent=2, sort_keys=True), encoding="utf-8")
tmp.replace(path)
return path
[docs]
def merge_config(base: dict[str, Any], overrides: dict[str, Any] | None) -> dict[str, Any]:
"""Recursively merge config dictionaries without mutating inputs."""
if not overrides:
return dict(base)
out: dict[str, Any] = dict(base)
for key, value in overrides.items():
current = out.get(key)
if isinstance(current, dict) and isinstance(value, dict):
out[key] = merge_config(current, value)
else:
out[key] = value
return out