from; } public function to(): int { return $this->to; } public function pageSize(): PageSize { return new PageSize($this->to - $this->from + 1); } public function pageNumber(): PageNumber { return new PageNumber((int) ($this->from / $this->pageSize()->value()) + 1); } public function equals(mixed $other): bool { return $other instanceof self && $this->from === $other->from && $this->to === $other->to; } public static function ofIndexes(int $from, int $to): self { $from = max(0, $from); $to = clamp($to, $from + 1, $from + self::MAX_PAGE_SIZE); return new self($from, $to); } public static function ofPage(PageNumber $pageNumber, PageSize $pageSize = new PageSize()): self { $fromIndex = ($pageNumber->value - 1) * $pageSize->value; $toIndex = $fromIndex + $pageSize->value - 1; return new self($fromIndex, $toIndex); } public static function ofOffsetAndLimit(int $offset, int $limit): self { $offset = max(0, $offset); $limit = clamp($limit, 1, self::MAX_PAGE_SIZE); $fromIndex = $offset; $toIndex = $offset + $limit - 1; return new self($fromIndex, $toIndex); } public static function firstPage(PageSize $pageSize = new PageSize()): self { return self::ofPage(new PageNumber(1), $pageSize); } public function __toString(): string { return sprintf('Pagination{from=%d, to=%d}', $this->from, $this->to); } }