Files
mcpacker/mcpacker/model/catalog.py
T

75 lines
2.2 KiB
Python

from collections.abc import Iterable
from typing import Any
from typing import Callable
from typing import Generic
from typing import Iterator
from typing import Protocol
from typing import TypeVar
# Type Support #####################################################################################
class HasGameId(Protocol):
@property
def gameId(self) -> str: ...
CatalogItem = TypeVar("CatalogItem", bound=HasGameId)
MapTarget = TypeVar("MapTarget")
# Class ############################################################################################
class Catalog(Generic[CatalogItem]):
def __init__(self, items:Iterable[CatalogItem]|None=None):
self._items:dict[str,CatalogItem] = {}
for item in (items or []):
self.add(item)
def __contains__(self, gameId:str) -> bool:
return gameId in self._items
def __delitem__(self, gameId:str):
del self._items[gameId]
def __eq__(self, other:Any) -> bool:
if type(self) != type(other): return False
if self._items != other._items: return False
return True
def __getitem__(self, gameId:str) -> CatalogItem:
return self._items[gameId]
def __iter__(self) -> Iterator[CatalogItem]:
for gameId in sorted([i.gameId for i in self._items.values()]):
yield self._items[gameId]
def __len__(self) -> int:
return len(self._items)
def __repr__(self) -> str:
return "".join(str(p) for p in [
self.__class__.__name__, "[",
", ".join(str(i) for i in self),
"]"
])
def add(self, item:CatalogItem) -> "Catalog[CatalogItem]":
if item.gameId in self._items:
raise Exception(f"Catalog already contains {item.gameId}")
self._items[item.gameId] = item
return self
def filter(self, isAllowed:Callable[[CatalogItem], bool]) -> Iterator[CatalogItem]:
for item in self:
if isAllowed(item):
yield item
def map(self, doTransform:Callable[[CatalogItem], MapTarget]) -> Iterator[MapTarget]:
for item in self:
yield doTransform(item)