Quizard/modules/constrains/__init__.py

107 lines
3.6 KiB
Python

from dataclasses import dataclass, field
from typing import Generic, Iterable, List, Protocol, Union, cast, overload, override
from modules.constrains.static import VTaskConstraintStatic
from modules.constrains.static.must_be_any import MustBeAnyConstraint
from modules.constrains.static.must_include_all_tags import MustIncludeAllTagsConstraint
from modules.constrains.static.must_include_any_tag import MustIncludeAnyTagConstraint
from modules.constrains.static.must_not import MustNotStatic
from modules.constrains.types import QTaskOrFactory
from modules.tags import Tag, Tags
from utils.types import A, C, Q, V
@dataclass
class VTaskConstraintsAbstract(Generic[C, V, Q, A]):
static_constraints: List[VTaskConstraintStatic[C, V, Q, A]] = field(
default_factory=list
)
dynamic_constraints: None = None
def add_constraint(
self, constraint: VTaskConstraintStatic[C, V, Q, A]
) -> "VTaskConstraints[C, V, Q, A]":
self.static_constraints.append(constraint)
# unsafe, but needed to avoid typing the same thing for two times...
return cast("VTaskConstraints[C, V, Q, A]", self)
def __call__(
self, constraint: VTaskConstraintStatic[C, V, Q, A]
) -> "VTaskConstraints[C, V, Q, A]":
return self.add_constraint(constraint)
@overload
def be_any(
self, item: Iterable[QTaskOrFactory[C, V, Q, A]]
) -> "VTaskConstraints[C, V, Q, A]": ...
@overload
def be_any(
self, item: QTaskOrFactory[C, V, Q, A], **kwargs: QTaskOrFactory[C, V, Q, A]
) -> "VTaskConstraints[C, V, Q, A]": ...
def be_any(
self,
item: Union[Iterable[QTaskOrFactory[C, V, Q, A]], QTaskOrFactory[C, V, Q, A]],
**kwargs: QTaskOrFabric[C, V, Q, A],
) -> "VTaskConstraints[C, V, Q, A]":
return self.add_constraint(MustBeAnyConstraint(item, **kwargs))
@overload
def include_any_tag(self, tag: Tags[C, V]) -> "VTaskConstraints[C, V, Q, A]": ...
@overload
def include_any_tag(
self, tag: Iterable[Tag[C, V]]
) -> "VTaskConstraints[C, V, Q, A]": ...
@overload
def include_any_tag(
self, tag: Tag[C, V], **kwargs: Tag[C, V]
) -> "VTaskConstraints[C, V, Q, A]": ...
def include_any_tag(
self,
tag: Union[Tags[C, V], Tag[C, V], Iterable[Tag[C, V]]],
**kwargs: Tag[C, V],
) -> "VTaskConstraints[C, V, Q, A]":
return self.add_constraint(MustIncludeAnyTagConstraint(tag, **kwargs))
@overload
def include_all_tags(self, tag: Tags[C, V]) -> "VTaskConstraints[C, V, Q, A]": ...
@overload
def include_all_tags(
self, tag: Iterable[Tag[C, V]]
) -> "VTaskConstraints[C, V, Q, A]": ...
@overload
def include_all_tags(
self, tag: Tag[C, V], **kwargs: Tag[C, V]
) -> "VTaskConstraints[C, V, Q, A]": ...
def include_all_tags(
self,
tag: Union[Tags[C, V], Tag[C, V], Iterable[Tag[C, V]]],
**kwargs: Tag[C, V],
):
return self.add_constraint(MustIncludeAllTagsConstraint(tag, **kwargs))
class VTaskConstraintsNegator(VTaskConstraintsAbstract[C, V, Q, A]):
def __init__(self, v_task_constraints: "VTaskConstraints[C, V, Q, A]"):
self.v_task_constraints = v_task_constraints
def add_constraint(
self, constraint: VTaskConstraintStatic[C, V, Q, A]
) -> "VTaskConstraints[C, V, Q, A]":
return self.v_task_constraints.add_constraint(MustNotStatic(constraint))
@dataclass
class VTaskConstraints(VTaskConstraintsAbstract[C, V, Q, A]):
nt: VTaskConstraintsNegator[C, V, Q, A] = field(init=False)
def __post_init__(self):
self.nt = VTaskConstraintsNegator(self)