$items */ private function __construct( private readonly array $items, ) {} public static function default(): self { return self::message(); } public static function summary(): self { return new self([ 'UID', 'FLAGS', 'INTERNALDATE', 'RFC822.SIZE', ]); } public static function message(): self { return self::summary() ->withEnvelope() ->withBodyStructure(); } public static function fullMessage(): self { return self::message()->withBodyText(); } public function withBodySection(string $section): self { $section = strtoupper(trim($section)); if ($section === '') { return $this; } return $this->with(sprintf('BODY[%s]', $section)); } public static function of(string ...$items): self { return new self(self::normalize($items)); } public function withUid(): self { return $this->with('UID'); } public function withFlags(): self { return $this->with('FLAGS'); } public function withInternalDate(): self { return $this->with('INTERNALDATE'); } public function withSize(): self { return $this->with('RFC822.SIZE'); } public function withEnvelope(): self { return $this->with('ENVELOPE'); } public function withBodyStructure(): self { return $this->with('BODYSTRUCTURE'); } public function withBodyText(): self { return $this->withBodySection('TEXT'); } public function withHeaderFields(string ...$fields): self { $fields = array_values(array_filter(array_map( static fn (string $field): string => strtoupper(trim($field)), $fields, ), static fn (string $field): bool => $field !== '')); if ($fields === []) { return $this; } return $this->with(sprintf('BODY.PEEK[HEADER.FIELDS (%s)]', implode(' ', $fields))); } public function with(string $item): self { return new self(self::normalize([ ...$this->items, $item, ])); } /** * @return list */ public function toArray(): array { return $this->items; } public function toCommand(): string { return implode(' ', $this->items); } /** * @param list $items * @return list */ private static function normalize(array $items): array { $normalized = []; foreach ($items as $item) { $item = trim($item); if ($item === '' || in_array($item, $normalized, true)) { continue; } $normalized[] = $item; } if (!in_array('UID', $normalized, true)) { array_unshift($normalized, 'UID'); } return $normalized; } }