walker: introduce Path classes
authorDmitry Selyutin <ghostmansd@gmail.com>
Wed, 21 Jun 2023 16:48:47 +0000 (19:48 +0300)
committerDmitry Selyutin <ghostmansd@gmail.com>
Wed, 21 Jun 2023 16:48:47 +0000 (19:48 +0300)
src/mdis/walker.py

index 4d1c33dbcf39bc3bd630c9ef7ec83611bf76b74b..55093556a1eacff5c18ebca0850cdcb94d0c4713 100644 (file)
@@ -13,30 +13,48 @@ class WalkerMeta(dispatcher.DispatcherMeta):
     pass
 
 
-class PartId(enum.Enum):
-    Index = enum.auto()
-    Attribute = enum.auto()
-    Hash = enum.auto()
+class GenericPath:
+    def __init__(self, path):
+        self.__path = path
+        return super().__init__()
 
-    def __call__(self, part):
-        return {
-            PartId.Index: "[{part}]",
-            PartId.Attribute: ".{part}",
-            PartId.Hash: "{{{part}}}",
-        }[self].format(part=part)
+    def __str__(self):
+        return self.__path.__str__()
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}({str(self)})"
+
+    @property
+    def path(self):
+        return self.__path
+
+
+class IndexPath(GenericPath):
+    def __str__(self):
+        return f"[{self.path}]"
+
+
+class AttributePath(GenericPath):
+    def __str__(self):
+        return f".{self.path}]"
+
+
+class HashPath(GenericPath):
+    def __str__(self):
+        return f"{{{self.path}}}"
 
 
 class Walker(dispatcher.Dispatcher, metaclass=WalkerMeta):
     @dispatcher.Hook(tuple, list)
     def dispatch_ordered_sequence(self, instance):
         for (index, item) in enumerate(instance):
-            yield (item, instance, index, PartId.Index)
+            yield (item, instance, index, IndexPath)
             yield from self(item)
 
     @dispatcher.Hook(set, frozenset)
     def dispatch_unordered_sequence(self, instance):
         for item in instance:
-            yield (item, instance, item, PartId.Hash)
+            yield (item, instance, item, HashPath)
             yield from self(item)
 
     @dispatcher.Hook(dataclasses.is_dataclass)
@@ -44,15 +62,15 @@ class Walker(dispatcher.Dispatcher, metaclass=WalkerMeta):
         for field in dataclasses.fields(instance):
             key = field.name
             value = getattr(instance, key)
-            yield (value, instance, key, PartId.Attribute)
+            yield (value, instance, key, AttributePath)
             yield from self(value)
 
     @dispatcher.Hook(dict)
     def dispatch_mapping(self, instance):
         for (key, value) in instance.items():
-            yield (key, instance, key, PartId.Hash)
+            yield (key, instance, key, HashPath)
             yield from self(key)
-            yield (value, instance, key, PartId.Index)
+            yield (value, instance, key, IndexPath)
             yield from self(value)
 
     @dispatcher.Hook(object)