Coverage for src / bluetooth_sig / registry / uuids / sdo_uuids.py: 90%
30 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-11 20:14 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-11 20:14 +0000
1"""SDO UUIDs registry for Bluetooth SIG Special Development Organization UUIDs."""
3from __future__ import annotations
5import re
7from bluetooth_sig.registry.base import BaseUUIDRegistry
8from bluetooth_sig.types.registry.sdo_uuids import SdoUuidInfo as SdoInfo
9from bluetooth_sig.types.uuid import BluetoothUUID
12class SdoUuidsRegistry(BaseUUIDRegistry[SdoInfo]):
13 """Registry for Bluetooth SIG Special Development Organization UUIDs."""
15 def _normalize_name_for_id(self, name: str) -> str:
16 """Normalize a name to create a valid ID string.
18 Args:
19 name: The name to normalize
21 Returns:
22 Normalized ID string
23 """
24 # Convert to lowercase, replace spaces and special chars with underscores
25 normalized = re.sub(r"[^a-zA-Z0-9]", "_", name.lower())
26 # Remove multiple consecutive underscores
27 normalized = re.sub(r"_+", "_", normalized)
28 # Remove leading/trailing underscores
29 normalized = normalized.strip("_")
30 return normalized
32 def _load_yaml_path(self) -> str:
33 """Return the YAML file path relative to bluetooth_sig/ root."""
34 return "assigned_numbers/uuids/sdo_uuids.yaml"
36 def _create_info_from_yaml(self, uuid_data: dict[str, str], uuid: BluetoothUUID) -> SdoInfo:
37 """Create SdoInfo from YAML data."""
38 name = uuid_data["name"]
39 return SdoInfo(
40 uuid=uuid,
41 name=name,
42 )
44 def _create_runtime_info(self, entry: object, uuid: BluetoothUUID) -> SdoInfo:
45 """Create runtime SdoInfo from entry."""
46 return SdoInfo(
47 uuid=uuid,
48 name=getattr(entry, "name", ""),
49 )
51 def get_sdo_info(self, uuid: str | BluetoothUUID) -> SdoInfo | None:
52 """Get SDO information by UUID.
54 Args:
55 uuid: The UUID to look up (string, int, or BluetoothUUID)
57 Returns:
58 SdoInfo if found, None otherwise
59 """
60 return self.get_info(uuid)
62 def get_sdo_info_by_name(self, name: str) -> SdoInfo | None:
63 """Get SDO information by name (case insensitive).
65 Args:
66 name: The SDO name to look up
68 Returns:
69 SdoInfo if found, None otherwise
70 """
71 return self.get_info(name)
73 def get_sdo_info_by_id(self, sdo_id: str) -> SdoInfo | None:
74 """Get SDO information by SDO ID.
76 Args:
77 sdo_id: The SDO ID to look up
79 Returns:
80 SdoInfo if found, None otherwise
81 """
82 return self.get_info(sdo_id)
84 def is_sdo_uuid(self, uuid: str | BluetoothUUID) -> bool:
85 """Check if a UUID corresponds to a known SDO.
87 Args:
88 uuid: The UUID to check
90 Returns:
91 True if the UUID is a known SDO, False otherwise
92 """
93 return self.get_sdo_info(uuid) is not None
95 def get_all_sdo_uuids(self) -> list[SdoInfo]:
96 """Get all SDO UUIDs in the registry.
98 Returns:
99 List of all SdoInfo objects
100 """
101 self._ensure_loaded()
102 return list(self._canonical_store.values())
105# Global instance for convenience
106sdo_uuids_registry = SdoUuidsRegistry.get_instance()