6d316ac61999029ed9acd194e8f2a7bc41db5c3d
[mdis.git] / src / mdis / walker.py
1 __all__ = [
2 "Walker",
3 "WalkerMeta",
4 ]
5
6 import enum
7 import dataclasses
8
9 from . import dispatcher
10
11
12 class WalkerMeta(dispatcher.DispatcherMeta):
13 pass
14
15
16 class GenericPath:
17 def __init__(self, path):
18 self.__path = path
19 return super().__init__()
20
21 def __str__(self):
22 return self.__path.__str__()
23
24 def __repr__(self):
25 return f"{self.__class__.__name__}({str(self)})"
26
27 @property
28 def path(self):
29 return self.__path
30
31
32 class IndexPath(GenericPath):
33 def __str__(self):
34 return f"[{self.path!r}]"
35
36
37 class AttributePath(GenericPath):
38 def __str__(self):
39 return f".{self.path}"
40
41
42 class HashPath(GenericPath):
43 def __str__(self):
44 return f"{{{self.path}}}"
45
46
47 class Walker(dispatcher.Dispatcher, metaclass=WalkerMeta):
48 @dispatcher.Hook(tuple, list)
49 def dispatch_ordered_sequence(self, node):
50 for (index, item) in enumerate(node):
51 yield index
52 yield item
53
54 @dispatcher.Hook(set, frozenset)
55 def dispatch_unordered_sequence(self, node):
56 for item in node:
57 yield item
58
59 @dispatcher.Hook(dataclasses.is_dataclass)
60 def dispatch_dataclass(self, node):
61 for field in dataclasses.fields(node):
62 key = field.name
63 value = getattr(node, key)
64 yield key
65 yield value
66
67 @dispatcher.Hook(dict)
68 def dispatch_mapping(self, node):
69 for (key, value) in node.items():
70 yield key
71 yield value
72
73 @dispatcher.Hook(object)
74 def dispatch_object(self, node):
75 yield from ()