from asyncio import Future
from collections.abc import Awaitable
from inspect import isawaitable
from typing import Any, TypeAlias, TypeVar

T = TypeVar("T")

MaybeAwaitable: TypeAlias = Awaitable[T] | T


async def maybe_awaitable(obj: MaybeAwaitable[T]) -> T:
    if isawaitable(obj):
        return await obj
    return obj


def safe_set_future_result(future: Future[T], value: T) -> bool:
    if not future.done():
        future.set_result(value)
        return True
    return False


def safe_set_future_exception(future: Future[Any], exc: BaseException) -> None:
    if not future.done():
        future.set_exception(exc)


__all__ = (
    "MaybeAwaitable",
    "maybe_awaitable",
    "safe_set_future_exception",
    "safe_set_future_result",
)
