Lines 100.00% 24 / 24
Functions and Methods 100.00% 2 / 2
Classes and Traits 100.00% 1 / 1
Name Lines Functions and Methods CRAP Classes and Traits
EventPayload 100.00% 24 / 24 100.00% 2 / 2 14 100.00% 1 / 1
 __construct 100.00% 6 / 6 100.00% 1 / 1 5
 assertTransportable 100.00% 18 / 18 100.00% 1 / 1 9
1<?php
2
3declare(strict_types=1);
4
5namespace Stewart\Support\Wire;
6
7use Stewart\Contracts\Exception\EventFireError;
8use Stewart\Contracts\Exception\EventFireException;
9
10/** @internal */
11final readonly class EventPayload
12{
13    private const string VALID_EVENT_TYPE_PATTERN = '/\A.{1,64}\z/su';
14
15    /**
16     * @param array<string, mixed> $data
17     * @throws EventFireException
18     */
19    public function __construct(
20        public string $eventType,
21        public array $data = [],
22    ) {
23        if (preg_match(self::VALID_EVENT_TYPE_PATTERN, $eventType) !== 1) {
24            throw EventFireException::createForReason(EventFireError::TypeInvalid, eventType: $eventType);
25        }
26
27        if ($data !== [] && array_is_list($data)) {
28            throw EventFireException::createForReason(EventFireError::DataNotKeyed, eventType: $eventType);
29        }
30
31        foreach ($data as $key => $value) {
32            $this->assertTransportable($value, (string) $key);
33        }
34    }
35
36    /** @throws EventFireException */
37    private function assertTransportable(mixed $value, string $path): void
38    {
39        if (\is_float($value) && !is_finite($value)) {
40            throw EventFireException::createForReason(
41                EventFireError::DataInvalid,
42                eventType: $this->eventType,
43                path: $path,
44                actualType: \sprintf('float(%s)', is_nan($value) ? 'NAN' : ($value > 0 ? 'INF' : '-INF')),
45            );
46        }
47
48        if ($value === null || \is_scalar($value)) {
49            return;
50        }
51
52        if (!\is_array($value)) {
53            throw EventFireException::createForReason(
54                EventFireError::DataInvalid,
55                eventType: $this->eventType,
56                path: $path,
57                actualType: get_debug_type($value),
58            );
59        }
60
61        foreach ($value as $key => $item) {
62            $this->assertTransportable($item, $path . '[' . $key . ']');
63        }
64    }
65}