import dataclasses import enum from collections.abc import Iterable from typing import Generic, Self, TypeVar T = TypeVar("T") NGrams = dict[int, list[str]] class Order(enum.Enum): ASC = "asc" DESC = "desc" class OrderBy(enum.Enum): TIMES_PLAYED = "times_played" LAST_PLAYED = "last_played" @dataclasses.dataclass(frozen=True) class OrderParams: order_by: OrderBy order: Order @dataclasses.dataclass(order=True) class SearchMatch: distance: float ngram: str @classmethod def combine_matches(cls, matches: Iterable[Self]) -> Self: ngrams, distances = zip(*((match.ngram, match.distance) for match in matches)) return cls( ngram=', '.join(ngrams), distance=sum(distances)/len(distances) ) @dataclasses.dataclass class QueryResult(Generic[T]): result: T distance: float ngram: str