From: Dmitry Selyutin Date: Tue, 20 Jun 2023 18:17:16 +0000 (+0300) Subject: walker: support path parts formatting X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c025a35e2d0f1fc3701d266aea52a0cb00abd8b7;p=mdis.git walker: support path parts formatting --- diff --git a/src/mdis/walker.py b/src/mdis/walker.py index a5762fa..578284e 100644 --- a/src/mdis/walker.py +++ b/src/mdis/walker.py @@ -3,6 +3,7 @@ __all__ = [ "WalkerMeta", ] +import enum import dataclasses from . import dispatcher @@ -12,27 +13,54 @@ class WalkerMeta(dispatcher.DispatcherMeta): pass +class PartId(enum.Enum): + Index = enum.auto() + Attribute = enum.auto() + Hash = enum.auto() + + def __call__(self, part): + return { + PartId.Index: "[{part}]", + PartId.Attribute: ".{part}", + PartId.Hash: "{{{part}}}", + }[self].format(part=part) + + class Walker(dispatcher.Dispatcher, metaclass=WalkerMeta): - @dispatcher.Hook(tuple, list, set, frozenset) - def dispatch_sequence(self, instance): - for item in instance: - yield item - yield from self(item) + @dispatcher.Hook(tuple, list) + def dispatch_ordered_sequence(self, instance, path=()): + for (index, item) in enumerate(instance): + part = (PartId.Index, index) + parts = (path + (part,)) + yield (item, parts) + yield from self(item, path=parts) - @dispatcher.Hook(dict) - def dispatch_mapping(self, instance): - for (key, value) in instance.items(): - yield (key, value) - yield from self((key, value)) + @dispatcher.Hook(set, frozenset) + def dispatch_unordered_sequence(self, instance, path=[]): + for item in instance: + part = (PartId.Hash, item) + parts = (path + (part,)) + yield (item, parts) + yield from self(item, path=parts) @dispatcher.Hook(dataclasses.is_dataclass) - def dispatch_dataclass(self, instance): + def dispatch_dataclass(self, instance, path=[]): for field in dataclasses.fields(instance): key = field.name value = getattr(instance, key) - yield (key, value) - yield from self((key, value)) + part = (PartId.Attribute, key) + parts = (path + (part,)) + yield (value, parts) + yield from self(value, path=parts) + + @dispatcher.Hook(dict) + def dispatch_mapping(self, instance, path=[]): + for (key, value) in instance.items(): + part = (PartId.Index, key) + parts = (path + (part,)) + yield (value, parts) + yield from self(value, path=parts) @dispatcher.Hook(object) - def dispatch_object(self, instance): + def dispatch_object(self, instance, path=()): yield from ()