Source code for magodo._magic

"""Contains the MagicTodoMixin class definition."""

from __future__ import annotations

import abc
import datetime as dt
from functools import total_ordering
import itertools as it
from typing import Any, List, Tuple, Type, TypeVar

from eris import ErisError, Err, Ok, Result

from ._todo import Todo, TodoMixin
from .types import LineSpell, Metadata, Priority, TodoSpell


M = TypeVar("M", bound="MagicTodoMixin")


[docs]@total_ordering class MagicTodoMixin(TodoMixin, abc.ABC): """Mixin class that implements the Todo protocol.""" pre_todo_spells: List[TodoSpell] = [] todo_spells: List[TodoSpell] = [] post_todo_spells: List[TodoSpell] = [] to_line_spells: List[LineSpell] = [] from_line_spells: List[LineSpell] = [] def __init__(self: M, todo: Todo): self._todo = todo self.todo = self.cast_todo_spells(todo)
[docs] @classmethod def from_line(cls: Type[M], line: str) -> Result[M, ErisError]: """Converts a string into a MagicTodo object.""" line = cls.cast_from_line_spells(line) todo_result = Todo.from_line(line) if isinstance(todo_result, Err): err: Err[Any, ErisError] = Err( "Failed to construct basic Todo object inside of MagicTodo." ) return err.chain(todo_result) todo = todo_result.ok() return Ok(cls(todo))
[docs] def to_line(self: M) -> str: """Converts this MagicTodo back to a string.""" line = self.todo.to_line() line = self.cast_to_line_spells(line) return line
[docs] @classmethod def cast_todo_spells(cls: Type[M], todo: Todo) -> Todo: """Casts all spells associated with this MagicTodo on `todo`.""" new_todo = todo.new() for todo_spell in it.chain( cls.pre_todo_spells, cls.todo_spells, cls.post_todo_spells ): new_todo = todo_spell(new_todo) return new_todo
[docs] @classmethod def cast_from_line_spells(cls: Type[M], line: str) -> str: """Casts all from_line spells on `line`.""" for line_spell in cls.from_line_spells: line = line_spell(line) return line
[docs] def cast_to_line_spells(self: M, line: str) -> str: """Casts all to_line spells on `line`.""" for line_spell in self.to_line_spells: line = line_spell(line) return line
[docs] def new(self: M, **kwargs: Any) -> M: """Creates a new Todo using the current Todo's attrs as defaults.""" return type(self)(self.todo.new(**kwargs))
@property def contexts(self: M) -> Tuple[str, ...]: # noqa: D102 return self.todo.contexts @property def create_date(self: M) -> dt.date: # noqa: D102 return self.todo.create_date @property def desc(self: M) -> str: # noqa: D102 return self.todo.desc @property def done_date(self: M) -> dt.date | None: # noqa: D102 return self.todo.done_date @property def done(self: M) -> bool: # noqa: D102 return self.todo.done @property def epics(self: M) -> Tuple[str, ...]: # noqa: D102 return self.todo.epics @property def metadata(self: M) -> Metadata: # noqa: D102 return self.todo.metadata @property def priority(self: M) -> Priority: # noqa: D102 return self.todo.priority @property def projects(self: M) -> Tuple[str, ...]: # noqa: D102 return self.todo.projects