mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2024-09-20 16:08:51 +03:00
630b401c01
* util: Implement `Paginator` class as interface to access a list by pages * Be less restrictive about page sizes and refactor tests * Make the pages based of 0 instead of 1 and some more test refactoring * More tests * Adjust workflows after rebase * Introduce `Paginator.create` * `<=` instead of `- 1`
47 lines
1.6 KiB
Python
47 lines
1.6 KiB
Python
from __future__ import annotations
|
|
|
|
import dataclasses
|
|
from math import ceil
|
|
from typing import Sequence
|
|
|
|
|
|
class InvalidPageSizeLimit(Exception):
|
|
def __init__(self, page_size_limit: int) -> None:
|
|
super().__init__(f"Page size limit must be one or more, not: {page_size_limit}")
|
|
|
|
|
|
class InvalidPageSizeError(Exception):
|
|
def __init__(self, page_size: int, page_size_limit: int) -> None:
|
|
super().__init__(f"Invalid page size {page_size}. Must be between: 1 and {page_size_limit}")
|
|
|
|
|
|
class PageOutOfBoundsError(Exception):
|
|
def __init__(self, page_size: int, max_page_size: int) -> None:
|
|
super().__init__(f"Page {page_size} out of bounds. Available pages: 0-{max_page_size}")
|
|
|
|
|
|
@dataclasses.dataclass
|
|
class Paginator:
|
|
_source: Sequence[object]
|
|
_page_size: int
|
|
|
|
@classmethod
|
|
def create(cls, source: Sequence[object], page_size: int, page_size_limit: int = 100) -> Paginator:
|
|
if page_size_limit < 1:
|
|
raise InvalidPageSizeLimit(page_size_limit)
|
|
if page_size > page_size_limit:
|
|
raise InvalidPageSizeError(page_size, page_size_limit)
|
|
return cls(source, page_size)
|
|
|
|
def page_size(self) -> int:
|
|
return self._page_size
|
|
|
|
def page_count(self) -> int:
|
|
return max(1, ceil(len(self._source) / self._page_size))
|
|
|
|
def get_page(self, page: int) -> Sequence[object]:
|
|
if page < 0 or page >= self.page_count():
|
|
raise PageOutOfBoundsError(page, self.page_count() - 1)
|
|
offset = page * self._page_size
|
|
return self._source[offset : offset + self._page_size]
|