60 lines
1.8 KiB
Python
60 lines
1.8 KiB
Python
"""Shared helpers for Elemental Imperium 33×33×6 wallet matrix labeling."""
|
||
|
||
from __future__ import annotations
|
||
|
||
|
||
def linear_index(lpbca: int, branch: int, class_: int) -> int:
|
||
return lpbca * 198 + branch * 6 + class_
|
||
|
||
|
||
def cell_id(lpbca: int, branch: int, class_: int) -> str:
|
||
return f"EI-L{lpbca:02d}-B{branch:02d}-C{class_}"
|
||
|
||
|
||
def build_label(network_code: str, cid: str, asn: int | None) -> str:
|
||
base = f"{network_code}.{cid}"
|
||
if asn is not None:
|
||
return f"{base}.AS{asn}"
|
||
return base
|
||
|
||
|
||
def match_range_rule(wallet: dict, match: dict) -> bool:
|
||
"""Each key in match is [min, max] inclusive for lpbca, branch, class. Empty {} matches all."""
|
||
dims = ("lpbca", "branch", "class")
|
||
for d in dims:
|
||
if d not in match:
|
||
continue
|
||
pair = match[d]
|
||
if not isinstance(pair, list) or len(pair) != 2:
|
||
raise ValueError(f"match.{d} must be [min, max]")
|
||
lo, hi = int(pair[0]), int(pair[1])
|
||
v = int(wallet[d])
|
||
if not (lo <= v <= hi):
|
||
return False
|
||
return True
|
||
|
||
|
||
def resolve_network_asn(
|
||
wallet: dict,
|
||
cid: str,
|
||
base_network: str,
|
||
base_asn: int | None,
|
||
overlay: dict | None,
|
||
) -> tuple[str, int | None]:
|
||
"""Apply rangeRules (first match wins), then cellOverrides."""
|
||
net, asn = base_network, base_asn
|
||
if overlay:
|
||
for rule in overlay.get("rangeRules", []):
|
||
if match_range_rule(wallet, rule.get("match") or {}):
|
||
net = rule["networkCode"]
|
||
if "asn" in rule:
|
||
asn = rule["asn"]
|
||
break
|
||
ovr = overlay.get("cellOverrides", {}).get(cid)
|
||
if isinstance(ovr, dict):
|
||
if "networkCode" in ovr:
|
||
net = ovr["networkCode"]
|
||
if "asn" in ovr:
|
||
asn = ovr["asn"]
|
||
return net, asn
|