Source code for osmium_chat.utils
from collections.abc import Container, Sequence
from typing import Protocol, TypeVar
__all__: tuple[str, ...] = (
"locate_created",
)
class Identifiable(Protocol):
"""Structural type for anything carrying an ``id`` and a ``name``.
Used by :func:`locate_created` so it can operate on any wrapped entity
(channels, roles, …) without importing their concrete classes.
"""
@property
def id(self) -> int | None: ...
@property
def name(self) -> str | None: ...
_T = TypeVar("_T", bound=Identifiable)
[docs]
def locate_created(before_ids: Container[object], after: Sequence[_T], name: str) -> _T | None:
"""Pick the entity just created out of a freshly fetched list.
Several Osmium create RPCs don't echo the new entity back, so the caller
snapshots the ids that existed beforehand, performs the create, refetches,
and uses this to find what appeared. Among the ids that are new we prefer a
name match and take the highest id (the most recently created); if nothing is
new we fall back to the newest name match across the whole list.
:param before_ids: The set of entity ids that existed before the create.
:param after: The entities fetched after the create.
:param name: The name the new entity was created with.
:returns: The created entity, or ``None`` if it could not be located.
"""
new = [item for item in after if item.id not in before_ids]
candidates = new or after
matches = [item for item in candidates if item.name == name] or candidates
return max(matches, key=lambda item: item.id or 0) if matches else None