> */ private const DOMAIN_MAPPERS = [ BadgeDomain::OperationRunStatus->value => Domains\OperationRunStatusBadge::class, BadgeDomain::OperationRunOutcome->value => Domains\OperationRunOutcomeBadge::class, BadgeDomain::InventorySyncRunStatus->value => Domains\InventorySyncRunStatusBadge::class, BadgeDomain::BackupScheduleRunStatus->value => Domains\BackupScheduleRunStatusBadge::class, BadgeDomain::BackupSetStatus->value => Domains\BackupSetStatusBadge::class, BadgeDomain::EntraGroupSyncRunStatus->value => Domains\EntraGroupSyncRunStatusBadge::class, BadgeDomain::RestoreRunStatus->value => Domains\RestoreRunStatusBadge::class, BadgeDomain::RestoreCheckSeverity->value => Domains\RestoreCheckSeverityBadge::class, BadgeDomain::FindingStatus->value => Domains\FindingStatusBadge::class, BadgeDomain::FindingSeverity->value => Domains\FindingSeverityBadge::class, BadgeDomain::BooleanEnabled->value => Domains\BooleanEnabledBadge::class, BadgeDomain::BooleanHasErrors->value => Domains\BooleanHasErrorsBadge::class, BadgeDomain::TenantStatus->value => Domains\TenantStatusBadge::class, BadgeDomain::TenantAppStatus->value => Domains\TenantAppStatusBadge::class, BadgeDomain::TenantRbacStatus->value => Domains\TenantRbacStatusBadge::class, BadgeDomain::TenantPermissionStatus->value => Domains\TenantPermissionStatusBadge::class, BadgeDomain::PolicySnapshotMode->value => Domains\PolicySnapshotModeBadge::class, BadgeDomain::PolicyRestoreMode->value => Domains\PolicyRestoreModeBadge::class, BadgeDomain::PolicyRisk->value => Domains\PolicyRiskBadge::class, BadgeDomain::IgnoredAt->value => Domains\IgnoredAtBadge::class, BadgeDomain::RestorePreviewDecision->value => Domains\RestorePreviewDecisionBadge::class, BadgeDomain::RestoreResultStatus->value => Domains\RestoreResultStatusBadge::class, ]; /** * @var array */ private static array $mapperCache = []; public static function spec(BadgeDomain $domain, mixed $value): BadgeSpec { $mapper = self::mapper($domain); if (! $mapper) { return BadgeSpec::unknown(); } try { return $mapper->spec($value); } catch (Throwable) { return BadgeSpec::unknown(); } } public static function mapper(BadgeDomain $domain): ?BadgeMapper { $key = $domain->value; if (array_key_exists($key, self::$mapperCache)) { return self::$mapperCache[$key]; } $mapper = self::buildMapper($domain); self::$mapperCache[$key] = $mapper; return $mapper; } public static function normalizeState(mixed $value): ?string { if ($value === null) { return null; } if ($value instanceof BackedEnum) { $value = $value->value; } if ($value instanceof Stringable) { $value = (string) $value; } if (is_bool($value)) { return $value ? 'true' : 'false'; } if (is_int($value) || is_float($value)) { return (string) $value; } if (! is_string($value)) { return null; } $normalized = strtolower(trim($value)); $normalized = str_replace([' ', '-'], '_', $normalized); return $normalized === '' ? null : $normalized; } private static function buildMapper(BadgeDomain $domain): ?BadgeMapper { $mapperClass = self::DOMAIN_MAPPERS[$domain->value] ?? null; if (! $mapperClass) { return null; } if (! class_exists($mapperClass)) { return null; } $mapper = new $mapperClass; return $mapper instanceof BadgeMapper ? $mapper : null; } }