Coverage for src / bluetooth_sig / registry / uuids / browse_groups.py: 81%

31 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-11 20:14 +0000

1"""Browse groups registry for Bluetooth SIG browse group definitions.""" 

2 

3from __future__ import annotations 

4 

5from bluetooth_sig.registry.base import BaseUUIDRegistry 

6from bluetooth_sig.types.registry.browse_group_identifiers import BrowseGroupInfo 

7from bluetooth_sig.types.uuid import BluetoothUUID 

8 

9 

10class BrowseGroupsRegistry(BaseUUIDRegistry[BrowseGroupInfo]): 

11 """Registry for Bluetooth SIG browse group identifiers.""" 

12 

13 def _load_yaml_path(self) -> str: 

14 """Return the YAML file path relative to bluetooth_sig/ root.""" 

15 return "assigned_numbers/uuids/browse_groups.yaml" 

16 

17 def _create_info_from_yaml(self, uuid_data: dict[str, str], uuid: BluetoothUUID) -> BrowseGroupInfo: 

18 """Create BrowseGroupInfo from YAML data.""" 

19 return BrowseGroupInfo( 

20 uuid=uuid, 

21 name=uuid_data["name"], 

22 id=uuid_data["id"], 

23 ) 

24 

25 def _create_runtime_info(self, entry: object, uuid: BluetoothUUID) -> BrowseGroupInfo: 

26 """Create runtime BrowseGroupInfo from entry.""" 

27 return BrowseGroupInfo( 

28 uuid=uuid, 

29 name=getattr(entry, "name", ""), 

30 id=getattr(entry, "id", ""), 

31 ) 

32 

33 def get_browse_group_info(self, uuid: str | BluetoothUUID) -> BrowseGroupInfo | None: 

34 """Get browse group information by UUID. 

35 

36 Args: 

37 uuid: The UUID to look up (string, int, or BluetoothUUID) 

38 

39 Returns: 

40 BrowseGroupInfo if found, None otherwise 

41 """ 

42 return self.get_info(uuid) 

43 

44 def get_browse_group_info_by_name(self, name: str) -> BrowseGroupInfo | None: 

45 """Get browse group information by name (case insensitive). 

46 

47 Args: 

48 name: The browse group name to look up 

49 

50 Returns: 

51 BrowseGroupInfo if found, None otherwise 

52 """ 

53 self._ensure_loaded() 

54 # Use the base class method or implement custom logic 

55 for info in self._canonical_store.values(): 

56 if info.name.lower() == name.lower(): 

57 return info 

58 return None 

59 

60 def get_browse_group_info_by_id(self, browse_group_id: str) -> BrowseGroupInfo | None: 

61 """Get browse group information by browse group ID. 

62 

63 Args: 

64 browse_group_id: The browse group ID to look up 

65 

66 Returns: 

67 BrowseGroupInfo if found, None otherwise 

68 """ 

69 self._ensure_loaded() 

70 for info in self._canonical_store.values(): 

71 if info.id == browse_group_id: 

72 return info 

73 return None 

74 

75 def is_browse_group_uuid(self, uuid: str | BluetoothUUID) -> bool: 

76 """Check if a UUID corresponds to a known browse group. 

77 

78 Args: 

79 uuid: The UUID to check 

80 

81 Returns: 

82 True if the UUID is a known browse group, False otherwise 

83 """ 

84 return self.get_info(uuid) is not None 

85 

86 def get_all_browse_groups(self) -> list[BrowseGroupInfo]: 

87 """Get all browse groups in the registry. 

88 

89 Returns: 

90 List of all BrowseGroupInfo objects 

91 """ 

92 self._ensure_loaded() 

93 return list(self._canonical_store.values()) 

94 

95 

96# Global instance for convenience 

97browse_groups_registry = BrowseGroupsRegistry.get_instance()