"""Helpers shared by the parsers. All pure: dict in, plain values out.""" from __future__ import annotations from collections.abc import Mapping from typing import Any # DMI defaults that board vendors leave in place (Supermicro boards ship most of them). PLACEHOLDERS = frozenset( { "to be filled by o.e.m.", "default string", "not specified", "not applicable", "n/a", "none", "0123456789", "system serial number", "system product name", "system manufacturer", } ) def text(value: Any) -> str | None: """A stripped string, ``None`` for missing or blank values.""" if value is None: return None value = str(value).strip() return value or None def ident(value: Any) -> str | None: """Like ``text``, but DMI placeholder strings count as missing too.""" value = text(value) if value is None or value.lower() in PLACEHOLDERS: return None return value def number(value: Any) -> float | None: """A float, ``None`` if the value is missing or not a number.""" if isinstance(value, bool) or value is None: return None try: return float(value) except (TypeError, ValueError): return None def integer(value: Any) -> int | None: if isinstance(value, bool) or value is None: return None try: return int(value) except (TypeError, ValueError): return None def boolean(value: Any) -> bool | None: return value if isinstance(value, bool) else None def odata_id(ref: Any) -> str | None: """The ``@odata.id`` of a reference object, or ``None``.""" if isinstance(ref, Mapping): return text(ref.get("@odata.id")) return None def link(resource: Mapping[str, Any], *keys: str) -> str | None: """Follow ``keys`` into nested objects and return the ``@odata.id`` found there.""" value: Any = resource for key in keys: if not isinstance(value, Mapping): return None value = value.get(key) return odata_id(value) def links(resource: Mapping[str, Any]) -> dict[str, str]: """All top-level properties of ``resource`` that are single references.""" found = {} for key, value in resource.items(): if key.startswith("@") or key == "Links": continue path = odata_id(value) if path is not None: found[key] = path return found def link_list(resource: Mapping[str, Any], *keys: str) -> list[str]: """The ``@odata.id`` of each reference in the array at ``keys``.""" value: Any = resource for key in keys: if not isinstance(value, Mapping): return [] value = value.get(key) if not isinstance(value, list): return [] return [path for path in (odata_id(ref) for ref in value) if path is not None] def status(resource: Mapping[str, Any]) -> tuple[str | None, str | None]: """``(Status.State, Status.Health)``.""" st = resource.get("Status") if not isinstance(st, Mapping): return None, None return text(st.get("State")), text(st.get("Health")) def present(resource: Mapping[str, Any]) -> bool: return status(resource)[0] != "Absent" def location_label(resource: Mapping[str, Any]) -> str | None: """``Location.PartLocation.ServiceLabel``, the printed label of a slot or bay.""" loc = resource.get("Location") if not isinstance(loc, Mapping): return None part = loc.get("PartLocation") if not isinstance(part, Mapping): return None return text(part.get("ServiceLabel")) def unique_name(names: Mapping[str, Any], name: str, suffix: Any) -> str: """``name``, or ``name (suffix)`` if it is already taken.""" if name not in names: return name candidate = f"{name} ({suffix})" n = 2 while candidate in names: candidate = f"{name} ({suffix}-{n})" n += 1 return candidate