55See LICENSE for details
66"""
77
8- from __future__ import annotations
9-
108import re
9+ from enum import Enum
10+
11+
12+ class PathPattern (Enum ):
13+ """Regex patterns and their replacements for normalizing dynamic path segments.
14+
15+ Each member is a (pattern, replacement) pair. Patterns are applied in
16+ declaration order -- put broader matches (e.g. UUIDs) before narrower ones.
17+ """
18+
19+ UUID = (r"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" , "{uuid}" )
20+ TOPIC = (r"(/topics/)([^/]+)" , r"\1{topic}" )
21+ SCHEMA_ID = (r"(/schemas/ids/)(\d+)" , r"\1{id}" )
22+ SUBJECT = (r"(/subjects/)([^/]+)" , r"\1{subject}" )
23+ VERSION = (r"(/versions/)(\d+)" , r"\1{version}" )
24+ CONFIG_SUBJECT = (r"(/config/)([^/]+)" , r"\1{subject}" )
25+ MODE_SUBJECT = (r"(/mode/)([^/]+)" , r"\1{subject}" )
1126
12- # UUIDs: 8-4-4-4-12 hex format
13- UUID_PATTERN = re .compile (r"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" )
14- # Topic names after /topics/ - match until next slash or end
15- TOPIC_PATTERN = re .compile (r"(/topics/)([^/]+)" )
16- # Schema IDs (numeric) after /schemas/ids/
17- SCHEMA_ID_PATTERN = re .compile (r"(/schemas/ids/)(\d+)" )
18- # Subject names after /subjects/
19- SUBJECT_PATTERN = re .compile (r"(/subjects/)([^/]+)" )
20- # Version numbers after /versions/
21- VERSION_PATTERN = re .compile (r"(/versions/)(\d+)" )
22- # Subject names after /config/
23- CONFIG_SUBJECT_PATTERN = re .compile (r"(/config/)([^/]+)" )
24- # Subject names after /mode/
25- MODE_SUBJECT_PATTERN = re .compile (r"(/mode/)([^/]+)" )
27+ def __init__ (self , pattern : str , replacement : str ) -> None :
28+ self .regex = re .compile (pattern )
29+ self .replacement = replacement
2630
2731
2832def normalize_path (path : str ) -> str :
@@ -33,17 +37,13 @@ def normalize_path(path: str) -> str:
3337
3438 Examples:
3539 /topics/my-topic -> /topics/{topic}
36- /consumers/abc-123-def /instances/xyz-456 -> /consumers/{uuid}/instances/{uuid}
40+ /consumers/3f410583-cfa3-48e8-bd9f-22eff1881c00 /instances/0333f5a1-d242-42bc-ba35-d7c5d67fc121 -> /consumers/{uuid}/instances/{uuid}
3741 /schemas/ids/42 -> /schemas/ids/{id}
3842 /subjects/my-subject/versions/3 -> /subjects/{subject}/versions/{version}
3943 /config/my-subject -> /config/{subject}
4044 /mode/my-subject -> /mode/{subject}
4145 """
42- normalized = UUID_PATTERN .sub ("{uuid}" , path )
43- normalized = TOPIC_PATTERN .sub (r"\1{topic}" , normalized )
44- normalized = SCHEMA_ID_PATTERN .sub (r"\1{id}" , normalized )
45- normalized = SUBJECT_PATTERN .sub (r"\1{subject}" , normalized )
46- normalized = VERSION_PATTERN .sub (r"\1{version}" , normalized )
47- normalized = CONFIG_SUBJECT_PATTERN .sub (r"\1{subject}" , normalized )
48- normalized = MODE_SUBJECT_PATTERN .sub (r"\1{subject}" , normalized )
46+ normalized = path
47+ for p in PathPattern :
48+ normalized = p .regex .sub (p .replacement , normalized )
4949 return normalized
0 commit comments