from typing import TypeGuard

from django.contrib.auth.models import AbstractBaseUser, AnonymousUser, User


def cast_user(user: AbstractBaseUser | AnonymousUser, cast: bool = False) -> TypeGuard[User]:
    """
    This function is a type-guard, making sure our ``request.user`` is ``User``.

    The type checker will infer request.user as ``AbstractBaseUser | AnonymousUser``.
    This usually isn't very useful, especially when working with a database, which expects
    a concrete model class.

    Since we're using the default ``django.contrib.auth``, we know ``request.user`` will hold
    an instance of :class:`django.contrib.auth.models.User`, and not some other class that
    implements :class:`AbstractBaseUser`, and if used on a `@login_required` decorated endpoint,
    it's pretty much guaranteed that this will pass.

    This function does perform an ``isinstance`` check, but if you set ``cast=True``, this check
    will be skipped and ``True`` will be returned immediately. This is useful for performance
    reasons, when we're certain that the user is logged in.
    """
    return cast or isinstance(user, User)
