Coverage for src / bluetooth_sig / registry / uuids / sdo_uuids.py: 90%
29 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-18 11:17 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-18 11:17 +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 return normalized.strip("_")
31 def _load_yaml_path(self) -> str:
32 """Return the YAML file path relative to bluetooth_sig/ root."""
33 return "assigned_numbers/uuids/sdo_uuids.yaml"
35 def _create_info_from_yaml(self, uuid_data: dict[str, str], uuid: BluetoothUUID) -> SdoInfo:
36 """Create SdoInfo from YAML data."""
37 name = uuid_data["name"]
38 return SdoInfo(
39 uuid=uuid,
40 name=name,
41 )
43 def _create_runtime_info(self, entry: object, uuid: BluetoothUUID) -> SdoInfo:
44 """Create runtime SdoInfo from entry."""
45 return SdoInfo(
46 uuid=uuid,
47 name=getattr(entry, "name", ""),
48 )
50 def get_sdo_info(self, uuid: str | BluetoothUUID) -> SdoInfo | None:
51 """Get SDO information by UUID.
53 Args:
54 uuid: The UUID to look up (string, int, or BluetoothUUID)
56 Returns:
57 SdoInfo if found, None otherwise
58 """
59 return self.get_info(uuid)
61 def get_sdo_info_by_name(self, name: str) -> SdoInfo | None:
62 """Get SDO information by name (case insensitive).
64 Args:
65 name: The SDO name to look up
67 Returns:
68 SdoInfo if found, None otherwise
69 """
70 return self.get_info(name)
72 def get_sdo_info_by_id(self, sdo_id: str) -> SdoInfo | None:
73 """Get SDO information by SDO ID.
75 Args:
76 sdo_id: The SDO ID to look up
78 Returns:
79 SdoInfo if found, None otherwise
80 """
81 return self.get_info(sdo_id)
83 def is_sdo_uuid(self, uuid: str | BluetoothUUID) -> bool:
84 """Check if a UUID corresponds to a known SDO.
86 Args:
87 uuid: The UUID to check
89 Returns:
90 True if the UUID is a known SDO, False otherwise
91 """
92 return self.get_sdo_info(uuid) is not None
94 def get_all_sdo_uuids(self) -> list[SdoInfo]:
95 """Get all SDO UUIDs in the registry.
97 Returns:
98 List of all SdoInfo objects
99 """
100 self._ensure_loaded()
101 return list(self._canonical_store.values())
104# Global instance for convenience
105sdo_uuids_registry = SdoUuidsRegistry.get_instance()