from abc import abstractmethod
from collections.abc import Callable
from typing import Protocol
from .attribute import AttributeMapping
from .datagraph import DataGraph, NodeEdgeFactory
from .datagraph import Edge as _Edge
from .datagraph import Node as _Node
[docs]
class StdNodeEdgeFactory[N: _Node, E: _Edge](NodeEdgeFactory):
def __init__(
self,
node_fn: Callable[[str, AttributeMapping], N],
edge_fn: Callable[[str, str, AttributeMapping], E],
) -> None:
self._node_fn = node_fn
self._edge_fn = edge_fn
[docs]
def node(self, name: str, attributes: AttributeMapping = AttributeMapping()) -> N:
return self._node_fn(name, attributes)
[docs]
def edge(
self, src: str, dst: str, attributes: AttributeMapping = AttributeMapping()
) -> E:
return self._edge_fn(src, dst, attributes)
[docs]
class DataGraphFactory[G: DataGraph](Protocol):
[docs]
def graph(self, attributes: AttributeMapping = AttributeMapping(), /) -> G: ...
[docs]
class StdDataGraphFactory[N: _Node, E: _Edge, G: DataGraph](DataGraphFactory[G]):
def __init__(
self,
node_edge: NodeEdgeFactory[N, E],
graph_fn: Callable[[NodeEdgeFactory[N, E], AttributeMapping], G],
):
self._node_edge = node_edge
self._graph_fn = graph_fn
[docs]
def graph(
self,
attributes: AttributeMapping = AttributeMapping(),
) -> G:
return self._graph_fn(
self._node_edge,
attributes,
)
[docs]
class IrFactory[N: _Node, E: _Edge, G: DataGraph](NodeEdgeFactory[N, E], Protocol):
[docs]
@abstractmethod
def graph(self, attributes: AttributeMapping = AttributeMapping(), /) -> G: ...
[docs]
class StdIrFactory[N: _Node, E: _Edge, G: DataGraph](StdNodeEdgeFactory[N, E]):
def __init__(
self,
node_fn: Callable[[str, AttributeMapping], N],
edge_fn: Callable[[str, str, AttributeMapping], E],
graph_fn: Callable[[NodeEdgeFactory[N, E], AttributeMapping], G],
) -> None:
super().__init__(node_fn, edge_fn)
self._graph = StdDataGraphFactory(self, graph_fn)
[docs]
def graph(self, attributes: AttributeMapping = AttributeMapping()) -> G:
return self._graph.graph(attributes)