Refactor radar system
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
"""Shared strict scalar and object readers for configuration codecs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
from typing import Any
|
||||
|
||||
|
||||
def json_object(value: Any, context: str) -> dict[str, Any]:
|
||||
"""Read an object; a missing or null section keeps its defaults."""
|
||||
if value is None:
|
||||
return {}
|
||||
if not isinstance(value, dict):
|
||||
raise ValueError(f"{context} must be a JSON object")
|
||||
return value
|
||||
|
||||
|
||||
def _value(payload: dict[str, Any], key: str, default: Any) -> Any:
|
||||
value = payload.get(key, default)
|
||||
return default if value is None else value
|
||||
|
||||
|
||||
def read_int(payload: dict[str, Any], key: str, default: int) -> int:
|
||||
"""Read a JSON integer without truncation or boolean coercion."""
|
||||
value = _value(payload, key, default)
|
||||
if isinstance(value, bool) or not isinstance(value, int):
|
||||
raise ValueError(f"{key} must be a JSON integer")
|
||||
return value
|
||||
|
||||
|
||||
def read_str(payload: dict[str, Any], key: str, default: str) -> str:
|
||||
"""Read a JSON string without converting other scalar types."""
|
||||
value = _value(payload, key, default)
|
||||
if not isinstance(value, str):
|
||||
raise ValueError(f"{key} must be a JSON string")
|
||||
return value
|
||||
|
||||
|
||||
def read_bool(payload: dict[str, Any], key: str, default: bool) -> bool:
|
||||
"""Read a JSON boolean."""
|
||||
value = _value(payload, key, default)
|
||||
if not isinstance(value, bool):
|
||||
raise ValueError(f"{key} must be a JSON boolean")
|
||||
return value
|
||||
|
||||
|
||||
def read_float(payload: dict[str, Any], key: str, default: float) -> float:
|
||||
"""Read a finite JSON number, including overflow-safe integer conversion."""
|
||||
return finite_number(_value(payload, key, default), key)
|
||||
|
||||
|
||||
def finite_number(value: Any, context: str) -> float:
|
||||
"""Validate a number without accepting booleans, strings or nonfinite values."""
|
||||
if isinstance(value, bool) or not isinstance(value, (int, float)):
|
||||
raise ValueError(f"{context} must be a JSON number")
|
||||
try:
|
||||
result = float(value)
|
||||
except OverflowError as exc:
|
||||
raise ValueError(f"{context} must be a finite number") from exc
|
||||
if not math.isfinite(result):
|
||||
raise ValueError(f"{context} must be a finite number")
|
||||
return result
|
||||
Reference in New Issue
Block a user