# Path: arq/typing.py
# WEEKDAYS = 'mon', 'tues', 'wed', 'thurs', 'fri', 'sat', 'sun'
# class WorkerCoroutine(Protocol):
# class StartupShutdown(Protocol):
# class WorkerSettingsBase(Protocol):
#     async def __call__(self, ctx: Dict[Any, Any], *args: Any, **kwargs: Any) -> Any:  # pragma: no cover
#     async def __call__(self, ctx: Dict[Any, Any]) -> Any:  # pragma: no cover
# 
# Path: arq/utils.py
# @overload
# def to_seconds(td: None) -> None:
#     pass


import asyncio
import dataclasses
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Optional, Union
from pydantic.utils import import_string
from .typing import WEEKDAYS, OptionType, SecondsTimedelta, WeekdayOptionType, WorkerCoroutine
from .utils import to_seconds
            micro = max(dt_.microsecond - options.microsecond, 0)
            if field == 'month':
                if dt_.month == 12:
                    return datetime(dt_.year + 1, 1, 1)
                else:
                    return datetime(dt_.year, dt_.month + 1, 1)
            elif field in ('day', 'weekday'):
                return (
                    dt_
                    + timedelta(days=1)
                    - timedelta(hours=dt_.hour, minutes=dt_.minute, seconds=dt_.second, microseconds=micro)
                )
            elif field == 'hour':
                return dt_ + timedelta(hours=1) - timedelta(minutes=dt_.minute, seconds=dt_.second, microseconds=micro)
            elif field == 'minute':
                return dt_ + timedelta(minutes=1) - timedelta(seconds=dt_.second, microseconds=micro)
            elif field == 'second':
                return dt_ + timedelta(seconds=1) - timedelta(microseconds=micro)
            else:
                assert field == 'microsecond', field
                return dt_ + timedelta(microseconds=options.microsecond - dt_.microsecond)
    return None


@dataclass
class CronJob:
    name: str
    coroutine: WorkerCoroutine
    month: OptionType
    day: OptionType

# Path: arq/typing.py
# WEEKDAYS = 'mon', 'tues', 'wed', 'thurs', 'fri', 'sat', 'sun'
# class WorkerCoroutine(Protocol):
# class StartupShutdown(Protocol):
# class WorkerSettingsBase(Protocol):
#     async def __call__(self, ctx: Dict[Any, Any], *args: Any, **kwargs: Any) -> Any:  # pragma: no cover
#     async def __call__(self, ctx: Dict[Any, Any]) -> Any:  # pragma: no cover
# 
# Path: arq/utils.py
# @overload
# def to_seconds(td: None) -> None:
#     pass


# Path: arq/cron.py
import asyncio
import dataclasses
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Optional, Union
from pydantic.utils import import_string
from .typing import WEEKDAYS, OptionType, SecondsTimedelta, WeekdayOptionType, WorkerCoroutine
from .utils import to_seconds

            micro = max(dt_.microsecond - options.microsecond, 0)
            if field == 'month':
                if dt_.month == 12:
                    return datetime(dt_.year + 1, 1, 1)
                else:
                    return datetime(dt_.year, dt_.month + 1, 1)
            elif field in ('day', 'weekday'):
                return (
                    dt_
                    + timedelta(days=1)
                    - timedelta(hours=dt_.hour, minutes=dt_.minute, seconds=dt_.second, microseconds=micro)
                )
            elif field == 'hour':
                return dt_ + timedelta(hours=1) - timedelta(minutes=dt_.minute, seconds=dt_.second, microseconds=micro)
            elif field == 'minute':
                return dt_ + timedelta(minutes=1) - timedelta(seconds=dt_.second, microseconds=micro)
            elif field == 'second':
                return dt_ + timedelta(seconds=1) - timedelta(microseconds=micro)
            else:
                assert field == 'microsecond', field
                return dt_ + timedelta(microseconds=options.microsecond - dt_.microsecond)
    return None


@dataclass
class CronJob:
    name: str
    coroutine: WorkerCoroutine
    month: OptionType
    day: OptionType

    weekday: WeekdayOptionType