from collections.abc import Callable, Iterable
from typing import Any, TypeVar, overload

from remedapy.decorator import make_data_last

Key = TypeVar('Key', str, int)


@overload
def keys(source: dict[Key, Any], /) -> Iterable[Key]: ...


@overload
@overload
def keys() -> Callable[[dict[Key, Any]], Iterable[Key]]: ...


@make_data_last
def keys(
    source: dict[Key, Any],
    /,
) -> Iterable[Key]:
    """
    Yields keys from dict.

    Parameters
    ----------
    source: dict[Any, T] | Iterable[T]
        Iterable or dict (positional-only).

    Yields
    ------
    T
        The values.

    Examples
    --------
    Data first:
    >>> list(R.keys({'a': 'x', 'b': 'y', '5': 'z'}))
    ['a', 'b', '5']

    Data last:
    >>> R.pipe({'a': 'x', 'b': 'y', '5': 'z'}, R.keys(), list)
    ['a', 'b', '5']

    """
    yield from source.keys()
