Coverage for src/bluetooth_sig/gatt/descriptors/registry.py: 79%
33 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-30 00:10 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-30 00:10 +0000
1"""Descriptor registry and resolution."""
3from __future__ import annotations
5from ...types.uuid import BluetoothUUID
6from .base import BaseDescriptor
9class DescriptorRegistry:
10 """Registry for descriptor classes."""
12 _registry: dict[str, type[BaseDescriptor]] = {}
14 @classmethod
15 def register(cls, descriptor_class: type[BaseDescriptor]) -> None:
16 """Register a descriptor class."""
17 # Create an instance to resolve the UUID
18 try:
19 instance = descriptor_class()
20 uuid_str = str(instance.uuid)
21 cls._registry[uuid_str] = descriptor_class
22 except (ValueError, TypeError, AttributeError):
23 # If we can't create an instance or resolve UUID, skip registration
24 pass
26 @classmethod
27 def get_descriptor_class(cls, uuid: str) -> type[BaseDescriptor] | None:
28 """Get descriptor class for UUID."""
29 # Convert to BluetoothUUID and use full form for lookup
30 try:
31 uuid_obj = BluetoothUUID(uuid)
32 full_uuid_str = uuid_obj.dashed_form
33 return cls._registry.get(full_uuid_str)
34 except ValueError:
35 return None
37 @classmethod
38 def create_descriptor(cls, uuid: str) -> BaseDescriptor | None:
39 """Create descriptor instance for UUID."""
40 descriptor_class = cls.get_descriptor_class(uuid)
41 if descriptor_class:
42 try:
43 return descriptor_class()
44 except (ValueError, TypeError, AttributeError):
45 return None
46 return None
48 @classmethod
49 def list_registered_descriptors(cls) -> list[str]:
50 """List all registered descriptor UUIDs."""
51 return list(cls._registry.keys())