*/ private array $numbers; private ?string $range; public function __construct(int ...$numbers) { $this->numbers = $numbers; $this->range = null; } public static function range(int $from, int $to): self { $set = new self(); $set->range = $from . ':' . $to; return $set; } /** * Build a SequenceSet that matches every message in the mailbox (1:*). */ public static function all(): self { $set = new self(); $set->range = '1:*'; return $set; } /** * Build a SequenceSet from a flat array of UIDs, collapsing consecutive * values into n:m ranges. * * Examples: * [1, 2, 3, 5, 6, 10] → "1:3,5:6,10" * [42] → "42" * [7, 3, 4, 5] → "3:5,7" * * @param int[] $uids */ public static function list(array $uids): self { if (empty($uids)) { return new self(); } $uids = array_unique($uids); sort($uids); $ranges = []; $start = $end = $uids[0]; for ($i = 1, $count = count($uids); $i <= $count; $i++) { $current = $uids[$i] ?? null; if ($current !== null && $current === $end + 1) { $end = $current; } else { $ranges[] = $start === $end ? (string) $start : $start . ':' . $end; if ($current !== null) { $start = $end = $current; } } } $set = new self(); $set->range = implode(',', $ranges); return $set; } public function __toString(): string { if ($this->range !== null) { return $this->range; } return implode(',', $this->numbers); } }