Lines
95.00%
38 / 40
Functions and Methods
75.00%
3 / 4
Classes and Traits
0.00%
0 / 1
| Name | Lines | Functions and Methods | CRAP | Classes and Traits | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| EventDecoder | 95.00% | 38 / 40 | 75.00% | 3 / 4 | 17 | 0.00% | 0 / 1 | |||
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| decodeStateChange | 88.23% | 15 / 17 | 0.00% | 0 / 1 | 6.06 | |||||
| decodeEvent | 100.00% | 13 / 13 | 100.00% | 1 / 1 | 6 | |||||
| decodeTriggerEvent | 100.00% | 9 / 9 | 100.00% | 1 / 1 | 4 | |||||
| 1 | <?php | |
| 2 | ||
| 3 | declare(strict_types=1); | |
| 4 | ||
| 5 | namespace Stewart\Client\Event; | |
| 6 | ||
| 7 | use Stewart\Client\State\EntityStateDecoder; | |
| 8 | use Stewart\Contracts\Event\EventOrigin; | |
| 9 | use Stewart\Contracts\Event\HaEvent; | |
| 10 | use Stewart\Contracts\State\EventContext; | |
| 11 | use Stewart\Contracts\State\StateChange; | |
| 12 | use Stewart\Contracts\State\StateChangeOrigin; | |
| 13 | use Stewart\Contracts\Trigger\TriggerEvent; | |
| 14 | use Stewart\Support\Json\JsonShape; | |
| 15 | ||
| 16 | final readonly class EventDecoder | |
| 17 | { | |
| 18 | public function __construct(private EntityStateDecoder $states) {} | |
| 19 | ||
| 20 | /** @param array<string, mixed> $event */ | |
| 21 | public function decodeStateChange(array $event): ?StateChange | |
| 22 | { | |
| 23 | $data = $event['data'] ?? null; | |
| 24 | ||
| 25 | if (!\is_array($data)) { | |
| 26 | return null; | |
| 27 | } | |
| 28 | ||
| 29 | $entityId = $this->states->parseEntityIdOrWarn($data['entity_id'] ?? null); | |
| 30 | ||
| 31 | if ($entityId === null) { | |
| 32 | return null; | |
| 33 | } | |
| 34 | ||
| 35 | $old = $data['old_state'] ?? null; | |
| 36 | $new = $data['new_state'] ?? null; | |
| 37 | $context = $event['context'] ?? null; | |
| 38 | ||
| 39 | return new StateChange( | |
| 40 | entityId: $entityId, | |
| 41 | from: \is_array($old) ? $this->states->decodeEntityStateOrSkip($old) : null, | |
| 42 | to: \is_array($new) ? $this->states->decodeEntityStateOrSkip($new) : null, | |
| 43 | firedAt: $this->states->parseInstantOrWarn($event['time_fired'] ?? null, $entityId->value, 'time_fired'), | |
| 44 | context: \is_array($context) ? EventContext::fromArray($context) : null, | |
| 45 | origin: StateChangeOrigin::Live, | |
| 46 | ); | |
| 47 | } | |
| 48 | ||
| 49 | /** @param array<string, mixed> $event */ | |
| 50 | public function decodeEvent(array $event): ?HaEvent | |
| 51 | { | |
| 52 | $type = $event['event_type'] ?? null; | |
| 53 | ||
| 54 | if (!\is_string($type) || $type === '') { | |
| 55 | return null; | |
| 56 | } | |
| 57 | ||
| 58 | $data = $event['data'] ?? null; | |
| 59 | $context = $event['context'] ?? null; | |
| 60 | $origin = $event['origin'] ?? null; | |
| 61 | ||
| 62 | return new HaEvent( | |
| 63 | type: $type, | |
| 64 | data: \is_array($data) ? JsonShape::treatKeysAsStrings($data) : [], | |
| 65 | origin: \is_string($origin) ? EventOrigin::tryFrom($origin) ?? EventOrigin::Local : EventOrigin::Local, | |
| 66 | firedAt: $this->states->parseInstantOrWarn($event['time_fired'] ?? null, $type, 'time_fired'), | |
| 67 | context: \is_array($context) ? EventContext::fromArray($context) : null, | |
| 68 | ); | |
| 69 | } | |
| 70 | ||
| 71 | /** @param array<string, mixed> $event */ | |
| 72 | public function decodeTriggerEvent(array $event): ?TriggerEvent | |
| 73 | { | |
| 74 | $variables = $event['variables'] ?? null; | |
| 75 | $trigger = \is_array($variables) ? $variables['trigger'] ?? null : null; | |
| 76 | ||
| 77 | if (!\is_array($trigger)) { | |
| 78 | return null; | |
| 79 | } | |
| 80 | ||
| 81 | $context = $event['context'] ?? null; | |
| 82 | ||
| 83 | return new TriggerEvent( | |
| 84 | trigger: JsonShape::treatKeysAsStrings($trigger), | |
| 85 | context: \is_array($context) ? EventContext::fromArray($context) : null, | |
| 86 | ); | |
| 87 | } | |
| 88 | } |