File size: 2,273 Bytes
07423df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
67
68
69
70
71
72
73
74
75
76
from collections import defaultdict
from dataclasses import dataclass
from typing import DefaultDict, List, Optional, Set, Union


@dataclass
class Dependency:
    """Dependency class.

    Args:
        key: key of the dependency
        value: required value of the dependency, None for empty condition
        is_set: whether the dependency should be set, or not set
    """

    key: str
    value: Union[str, bool, int, None] = True
    is_set: bool = True

    def check(self, dependency_values: Optional[List[str]]) -> bool:
        """
        Check if dependency is satisfied

        Args:
            dependency_values: list of dependency values

        Returns:
            True if the dependency is satisfied, False otherwise
        """

        if dependency_values is None:
            dependency_values = []

        if self.value is None and self.is_set and len(dependency_values):
            return False
        elif self.value is None and not self.is_set and not len(dependency_values):
            return False
        elif self.is_set and self.value not in dependency_values:
            return False
        elif (
            not self.is_set
            and len([v for v in dependency_values if v != self.value]) == 0
        ):
            return False
        return True


class Nesting:
    """
    A tree-like structure to specify nested dependencies of key-value pairs
    In detail it maps dependencies of key requiring any number of key:value pairs

    Primarily useful for specifying nested dependencies of UI elements shown in Wave.
    """

    def __init__(self):
        self.dependencies: DefaultDict[str, List[Dependency]] = defaultdict(list)
        self.triggers: Set[str] = set()

    def add(self, keys: List[str], dependencies: List[Dependency]):
        """
        Append dependencies (key:value) for a given key

        Args:
            keys: keys to add dependencies for
            dependencies: key:value pairs to depend on
        """

        if len(set(keys)) != len(keys):
            raise ValueError("Nesting keys must be unique.")

        for dependency in dependencies:
            self.triggers.add(dependency.key)
            for key in set(keys):
                self.dependencies[key].append(dependency)