Functional Weave
Code in Python

todo.recurrence-label@1.0.0

impl/python.py

1,824 bytes · the Python implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

from .dates_add_days import parse_iso_date  ← from dates.add-days ^1.0.0 · built alongside by fune
from .dates_day_of_week import day_name  ← from dates.day-of-week ^1.0.0 · built alongside by fune
from .todo_item import Recurrence  ← from todo.item ^1.0.0 · built alongside by fune

_MONTHS = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
_FREQUENCIES = ("daily", "weekdays", "weekly", "monthly", "yearly")


def _ordinal(n: int) -> str:
    """1st, 2nd, 3rd, 4th ... 11th, 12th, 13th ... 21st, 22nd, 23rd ... 31st."""
    if 11 <= n % 100 <= 13:
        return f"{n}th"
    suffix = {1: "st", 2: "nd", 3: "rd"}.get(n % 10, "th")
    return f"{n}{suffix}"


def _every(interval: int, unit: str) -> str:
    return f"Every {unit}" if interval == 1 else f"Every {interval} {unit}s"


def recurrence_label(recurrence: Recurrence) -> str:
    """English words for a repeat rule; the weekday, day and date come from the anchor."""
    frequency, interval, anchor = recurrence.frequency, recurrence.interval, recurrence.anchor
    if frequency not in _FREQUENCIES:
        raise ValueError(f'unknown repeat frequency "{frequency}": expected daily, weekdays, weekly, monthly or yearly')
    if isinstance(interval, bool) or not isinstance(interval, int) or interval < 1:
        raise ValueError(f"repeat interval must be 1 or more, received {interval}")
    if frequency == "weekdays" and interval != 1:
        raise ValueError(f"weekday repeats cannot skip weeks: interval must be 1, received {interval}")
    date = parse_iso_date(anchor)
    if frequency == "daily":
        return _every(interval, "day")
    if frequency == "weekdays":
        return "Every weekday"
    if frequency == "weekly":
        return f"{_every(interval, 'week')} on {day_name(anchor)}"
    if frequency == "monthly":
        return f"{_every(interval, 'month')} on the {_ordinal(date.day)}"
    return f"{_every(interval, 'year')} on {date.day} {_MONTHS[date.month - 1]}"