feat: initial version

Signed-off-by: Sebastian Krupinski <root@LAPTOP-7DVOR6NC>
This commit is contained in:
Sebastian Krupinski
2026-02-20 16:41:19 -05:00
commit 7f562d6aba
139 changed files with 11256 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Protocol\Command\Argument;
interface Argument
{
public function __toString(): string;
}

View File

@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Protocol\Command\Argument;
use DateTimeInterface;
readonly class Date implements Argument
{
public function __construct(private DateTimeInterface $value)
{
}
public static function tryFrom(?DateTimeInterface $value): ?self
{
return is_null($value) ? null : new self($value);
}
public function __toString(): string
{
return $this->value->format('d-M-Y');
}
}

View File

@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Protocol\Command\Argument;
use DateTimeInterface;
readonly class DateTime implements Argument
{
public function __construct(private DateTimeInterface $value)
{
}
public static function tryFrom(?DateTimeInterface $value): ?self
{
return is_null($value) ? null : new self($value);
}
public function __toString(): string
{
return '"'.$this->value->format('d-M-Y H:i:s O').'"';
}
}

View File

@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Protocol\Command\Argument;
final readonly class ParenthesizedList implements Argument
{
/**
* @param list<string> $items
*/
public function __construct(public array $items)
{
}
/**
* @param list<string> $items
*/
public static function tryFrom(?array $items): ?self
{
return empty($items) ? null : new self($items);
}
public function __toString(): string
{
return sprintf('(%s)', implode(' ', $this->items));
}
}

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Protocol\Command\Argument;
final readonly class QuotedString implements Argument
{
public function __construct(private string $value)
{
}
public function __toString(): string
{
return sprintf('"%s"', $this->value);
}
}

View File

@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Protocol\Command\Argument\Search;
class All implements Criteria
{
public function __toString(): string
{
return 'ALL';
}
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Protocol\Command\Argument\Search;
use Gricob\IMAP\Protocol\Command\Argument\Date;
readonly class Before extends Date implements Criteria
{
public function __toString(): string
{
return 'BEFORE '.parent::__toString();
}
}

View File

@@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Protocol\Command\Argument\Search;
use Gricob\IMAP\Protocol\Command\Argument\Argument;
interface Criteria extends Argument
{
}

View File

@@ -0,0 +1,19 @@
<?php
namespace Gricob\IMAP\Protocol\Command\Argument\Search;
use Gricob\IMAP\Protocol\Command\Argument\QuotedString;
class Header implements Criteria
{
public function __construct(
private string $fieldName,
private string $value,
) {
}
public function __toString(): string
{
return sprintf('HEADER %s %s', $this->fieldName, new QuotedString($this->value));
}
}

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Protocol\Command\Argument\Search;
final readonly class Not implements Criteria
{
public function __construct(private Criteria $criteria)
{
}
public function __toString(): string
{
return 'NOT ('.$this->criteria.')';
}
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Protocol\Command\Argument\Search;
use Gricob\IMAP\Protocol\Command\Argument\Date;
readonly class Since extends Date implements Criteria
{
public function __toString(): string
{
return 'SINCE '.parent::__toString();
}
}

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Protocol\Command\Argument;
final class SequenceSet implements Argument
{
/**
* @var array<int>
*/
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;
}
public function __toString(): string
{
if ($this->range !== null) {
return $this->range;
}
return implode(',', $this->numbers);
}
}

View File

@@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Protocol\Command\Argument\Store;
use Gricob\IMAP\Protocol\Command\Argument\Argument;
final readonly class Flags implements Argument
{
/**
* @param list<string> $flags
*/
public function __construct(
private array $flags,
private string $modifier = '',
private bool $silent = true,
) {
}
public function __toString(): string
{
return sprintf(
'%sFLAGS%s (%s)',
$this->modifier,
$this->silent ? '.SILENT' : '',
implode(' ', $this->flags),
);
}
}

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Gricob\IMAP\Protocol\Command\Argument;
final readonly class SynchronizingLiteral implements Argument
{
public function __construct(private string $value)
{
}
public function __toString(): string
{
return sprintf(
'{%s}',
strlen($this->value)
);
}
}