from __future__ import annotations from dataclasses import dataclass from typing import Any FORMATTER_TARGETS = ("auto", "single", "softcore", "hardcore") PAIR_SIDE_TARGETS = ("softcore", "hardcore") DEFAULT_FORMATTER_TARGET = "auto" DEFAULT_PAIR_SELECTED_SIDE = "softcore" _TARGET_ALIASES = { "soft": "softcore", "soft_core": "softcore", "hard": "hardcore", "hard_core": "hardcore", } @dataclass(frozen=True) class PairTargetPolicy: target: str pair_target: str selected_side: str include_softcore: bool include_hardcore: bool def normalize_target(value: Any) -> str: target = str(value or "").strip().lower().replace("-", "_").replace(" ", "_") target = _TARGET_ALIASES.get(target, target) return target if target in FORMATTER_TARGETS else DEFAULT_FORMATTER_TARGET def pair_target(value: Any) -> str: target = normalize_target(value) return target if target in PAIR_SIDE_TARGETS else DEFAULT_FORMATTER_TARGET def pair_selected_side(value: Any, default: str = DEFAULT_PAIR_SELECTED_SIDE) -> str: side = pair_target(value) if side in PAIR_SIDE_TARGETS: return side return default if default in PAIR_SIDE_TARGETS else DEFAULT_PAIR_SELECTED_SIDE def pair_policy(value: Any, *, selected_default: str = DEFAULT_PAIR_SELECTED_SIDE) -> PairTargetPolicy: target = normalize_target(value) side_target = pair_target(target) selected_side = pair_selected_side(side_target, selected_default) return PairTargetPolicy( target=target, pair_target=side_target, selected_side=selected_side, include_softcore=side_target in ("auto", "softcore"), include_hardcore=side_target in ("auto", "hardcore"), )