diff --git a/src/DefaultHeadersDecorator.php b/src/DefaultHeadersDecorator.php index 46545066..8b8aa89a 100644 --- a/src/DefaultHeadersDecorator.php +++ b/src/DefaultHeadersDecorator.php @@ -12,8 +12,10 @@ class DefaultHeadersDecorator implements MessageDecorator { private ClassNameInflector $inflector; private Clock|ClockInterface $clock; + /** @var non-empty-string */ private string $timeOfRecordingFormat; + /** @param non-empty-string $timeOfRecordingFormat */ public function __construct( ?ClassNameInflector $inflector = null, null|Clock|ClockInterface $clock = null, diff --git a/src/Message.php b/src/Message.php index 11e61c60..6ddddc34 100644 --- a/src/Message.php +++ b/src/Message.php @@ -9,15 +9,29 @@ /** * @template TId of AggregateRootId = AggregateRootId + * @template TPayload of object = object + * + * @phpstan-type HeaderValue int|string|array|TId|null|bool|float + * @phpstan-type HeadersShape array */ final class Message { public const TIME_OF_RECORDING_FORMAT = 'Y-m-d H:i:s.uO'; + /** + * @param TPayload $payload + * @param HeadersShape $headers + */ public function __construct(private object $payload, private array $headers = []) { } + /** + * @param non-empty-string $key + * @param HeaderValue $value + * + * @return Message + */ public function withHeader(string $key, int|string|array|AggregateRootId|null|bool|float $value): Message { $clone = clone $this; @@ -26,6 +40,11 @@ public function withHeader(string $key, int|string|array|AggregateRootId|null|bo return $clone; } + /** + * @param HeadersShape $headers + * + * @return Message + */ public function withHeaders(array $headers): Message { $clone = clone $this; @@ -34,6 +53,11 @@ public function withHeaders(array $headers): Message return $clone; } + /** + * @param non-empty-string $format + * + * @return Message + */ public function withTimeOfRecording( DateTimeImmutable $timeOfRecording, string $format = self::TIME_OF_RECORDING_FORMAT @@ -47,6 +71,7 @@ public function withTimeOfRecording( public function aggregateVersion(): int { $version = $this->headers[Header::AGGREGATE_ROOT_VERSION] ?? null; + \assert($version === null || \is_numeric($version)); if ($version === null) { throw new RuntimeException("Can't get the version if the message has none."); @@ -60,23 +85,28 @@ public function aggregateVersion(): int */ public function aggregateRootId(): ?AggregateRootId { - return $this->headers[Header::AGGREGATE_ROOT_ID] ?? null; + $aggregateRootId = $this->headers[Header::AGGREGATE_ROOT_ID] ?? null; + \assert($aggregateRootId === null || $aggregateRootId instanceof AggregateRootId); + + return $aggregateRootId; } public function aggregateRootType(): ?string { - return $this->headers[Header::AGGREGATE_ROOT_TYPE] ?? null; + $aggregateRootType = $this->headers[Header::AGGREGATE_ROOT_TYPE] ?? null; + \assert($aggregateRootType === null || \is_string($aggregateRootType)); + + return $aggregateRootType; } public function timeOfRecording(): DateTimeImmutable { $format = $this->headers[Header::TIME_OF_RECORDING_FORMAT] ?? self::TIME_OF_RECORDING_FORMAT; + $header = $this->headers[Header::TIME_OF_RECORDING] ?? ''; + \assert(\is_string($format)); + \assert(\is_string($header)); - /* @var DateTimeImmutable */ - $timeOfRecording = DateTimeImmutable::createFromFormat( - '!' . $format, - $header = (string) ($this->headers[Header::TIME_OF_RECORDING] ?? '') - ); + $timeOfRecording = \DateTimeImmutable::createFromFormat('!' . $format, $header); if ( ! $timeOfRecording instanceof DateTimeImmutable) { throw UnableToResolveTimeOfRecording::fromFormatAndHeader($format, $header); @@ -85,16 +115,27 @@ public function timeOfRecording(): DateTimeImmutable return $timeOfRecording; } - public function header(string $key): int|string|array|AggregateRootId|null|bool|float + /** + * @param non-empty-string $key + * + * @return HeaderValue + */ + public function header(string $key): int|string|array|AggregateRootId|bool|float|null { return $this->headers[$key] ?? null; } + /** + * @return HeadersShape + */ public function headers(): array { return $this->headers; } + /** + * @return TPayload + */ public function payload(): object { return $this->payload; @@ -102,6 +143,8 @@ public function payload(): object /** * @deprecated use ->payload instead + * + * @return TPayload */ public function event(): object {