aboutsummaryrefslogtreecommitdiffstats
path: root/bsie/utils/node.py
blob: fa34b2e0c08dc54918a2c6b86061d407dea63c68 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
"""Lighweight Node to bridge to BSFS.
"""
# standard imports
import typing

# bsie imports
from bsie.utils import bsfs

# exports
__all__: typing.Sequence[str] = (
    'Node',
    )


## code ##

class Node():
    """Lightweight Node, disconnected from any bsfs structures.

    In most cases, provide *hints* and leave setting the uri to a node
    naming policy. Only provide an *uri* if it is absolutely determined.

    """

    # node type.
    node_type: bsfs.URI

    # node URI.
    uri: typing.Optional[bsfs.URI]

    # node naming hints.
    hits: dict

    def __init__(
            self,
            node_type: bsfs.URI,
            uri: typing.Optional[bsfs.URI] = None,
            **uri_hints,
            ):
        # assign members
        self.node_type = bsfs.URI(node_type)
        self.hints = uri_hints
        self.uri = uri

    def __eq__(self, other: typing.Any) -> bool:
        """Compare two Node instances based on type and uri.
        Compares hits only if the uri is not yet specified.
        """
        return isinstance(other, Node) \
            and other.node_type == self.node_type \
            and other.uri == self.uri \
            and (self.uri is not None or self.hints == other.hints)

    def __hash__(self) -> int:
        identifier = self.uri
        if identifier is None:
            identifier = tuple((key, self.hints[key]) for key in sorted(self.hints))
        return hash((type(self), self.node_type, identifier))

    def __str__(self) -> str:
        return f'{bsfs.typename(self)}({self.node_type}, {self.uri})'

    def __repr__(self) -> str:
        return f'{bsfs.typename(self)}({self.node_type}, {self.uri})'

## EOF ##