Source code for magodo.types

"""Custom types used by this library."""

from __future__ import annotations

import datetime as dt
from typing import (
    Any,
    Callable,
    Dict,
    Generic,
    List,
    Literal,
    Protocol,
    Tuple,
    Type,
    TypeVar,
    runtime_checkable,
)

from eris import ErisError, Result
from typist import Comparable


# Type Variables (i.e. `TypeVar`s)
T = TypeVar("T", bound="AbstractTodo")

# Type of the Todo.metadata attribute.
Metadata = Dict[str, str]
# A todo item's priority is always a capital letter.
Priority = Literal[
    "A",
    "B",
    "C",
    "D",
    "E",
    "F",
    "G",
    "H",
    "I",
    "J",
    "K",
    "L",
    "M",
    "N",
    "O",
    "P",
    "Q",
    "R",
    "S",
    "T",
    "U",
    "V",
    "W",
    "X",
    "Y",
    "Z",
]

# Type of a spell function which transforms a line (i.e. a str).
LineSpell = Callable[[str], str]
# Type of spell functions used by MagicTodo objects.
TodoSpell = Callable[[T], T]

SinglePredicate = Callable[[str], bool]
DoublePredicate = Callable[[str, str], bool]


[docs]@runtime_checkable class AbstractTodo(Comparable, Protocol): """Describes how any valid Todo object should look.""" @property def ident(self) -> str: """A unique identifier for this Todo."""
[docs] @classmethod def from_line(cls: Type[T], line: str) -> Result[T, ErisError]: """Constructs a new Todo object from a string."""
[docs] def to_line(self) -> str: """Converts a Todo object back to a string."""
[docs] def new(self: T, **kwargs: Any) -> T: """Creates a new Todo using the current Todo's attrs as defaults."""
@property def contexts(self) -> Tuple[str, ...]: # noqa: D102 """A todo's contexts. A word is normally marked as a context by prefixing it with '@'. """ @property def create_date(self) -> dt.date: # noqa: D102 """The date this todo was created.""" @property def desc(self) -> str: # noqa: D102 """A description of this todo.""" @property def done_date(self) -> dt.date | None: # noqa: D102 """The date this todo was completed.""" @property def done(self) -> bool: # noqa: D102 """Is this todo marked done with an 'x'?""" @property def epics(self) -> Tuple[str, ...]: # noqa: D102 """A todo's epics. A word is normally marked as an epic by prefixing it with '#'. """ @property def metadata(self) -> Metadata: # noqa: D102 """A todo's corresponding metadata dictionary. A word is metadata if it is of the form KEY:VALUE. """ @property def priority(self) -> Priority: # noqa: D102 """A todo's priority.""" @property def projects(self) -> Tuple[str, ...]: # noqa: D102 """A todo's projects. A word is normally marked as a project by prefixing it with '+'. """
[docs]@runtime_checkable class AbstractMagicTodo(AbstractTodo, Protocol, Generic[T]): """Describes how subclasses of MagicTodoMixin should look.""" to_line_spells: List[LineSpell] from_line_spells: List[LineSpell] pre_todo_spells: List[TodoSpell] todo_spells: List[TodoSpell] post_todo_spells: List[TodoSpell] def __init__(self, todo: T) -> None: pass
[docs] @classmethod def cast_todo_spells(cls, todo: T) -> Result[T, ErisError]: """Casts all spells associated with this MagicTodo on `todo`."""
[docs] @classmethod def cast_from_line_spells(cls, line: str) -> str: """Casts all from_line spells on `line`."""
[docs] def cast_to_line_spells(self, line: str) -> str: """Casts all to_line spells on `line`."""
@property def todo(self) -> T: """The raw Todo object used by this MagicTodo."""