# standard imports import abc import typing # bsie imports from bsie.utils import bsfs # inner-module imports from . import nodes # exports __all__: typing.Sequence[str] = ( 'Matcher', ) ## code ## class Matcher(): """Determine node uri's from node hints.""" def __call__( self, iterable: typing.Iterable[typing.Tuple[nodes.Node, bsfs.URI, typing.Any]], ): """Apply the matcher on a triple iterator.""" return MatcherIterator(self, iterable) @abc.abstractmethod def match_node(self, node: nodes.Node) -> nodes.Node: """Apply the matcher on a node.""" class MatcherIterator(): """Iterates over triples, determines uris according to a *matcher* as it goes.""" # source triple iterator. _iterable: typing.Iterable[typing.Tuple[nodes.Node, bsfs.URI, typing.Any]] # node matcher _matcher: Matcher def __init__( self, matcher: Matcher, iterable: typing.Iterable[typing.Tuple[nodes.Node, bsfs.URI, typing.Any]], ): self._iterable = iterable self._matcher = matcher def __iter__(self): for node, pred, value in self._iterable: # handle subject self._matcher.match_node(node) # handle value if isinstance(value, nodes.Node): self._matcher.match_node(value) # yield triple yield node, pred, value ## EOF ##