Lines 100.00% 18 / 18
Functions and Methods 100.00% 4 / 4
Classes and Traits 100.00% 1 / 1
Name Lines Functions and Methods CRAP Classes and Traits
HaConfig 100.00% 18 / 18 100.00% 4 / 4 15 100.00% 1 / 1
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 fromGetConfigResult 100.00% 6 / 6 100.00% 1 / 1 4
 parseTimeZone 100.00% 3 / 3 100.00% 1 / 1 2
 parseLocation 100.00% 8 / 8 100.00% 1 / 1 8
1<?php
2
3declare(strict_types=1);
4
5namespace Stewart\Client;
6
7use DateTimeZone;
8use Exception;
9use Stewart\Contracts\Exception\SunException;
10use Stewart\Contracts\Sun\GeoLocation;
11
12final readonly class HaConfig
13{
14    public function __construct(
15        public ?string $timeZoneName = null,
16        public ?DateTimeZone $timeZone = null,
17        public ?HaCoreState $coreState = null,
18        public ?GeoLocation $location = null,
19    ) {}
20
21    /** @param array<array-key, mixed> $result */
22    public static function fromGetConfigResult(array $result): self
23    {
24        $timeZoneName = $result['time_zone'] ?? null;
25        $coreState = \is_string($result['state'] ?? null) ? HaCoreState::tryFrom($result['state']) : null;
26        $location = self::parseLocation($result);
27
28        if (!\is_string($timeZoneName) || $timeZoneName === '') {
29            return new self(coreState: $coreState, location: $location);
30        }
31
32        return new self($timeZoneName, self::parseTimeZone($timeZoneName), $coreState, $location);
33    }
34
35    private static function parseTimeZone(string $name): ?DateTimeZone
36    {
37        try {
38            return new DateTimeZone($name);
39        } catch (Exception) {
40            return null;
41        }
42    }
43
44    /** @param array<array-key, mixed> $result */
45    private static function parseLocation(array $result): ?GeoLocation
46    {
47        $latitude = $result['latitude'] ?? null;
48        $longitude = $result['longitude'] ?? null;
49        $elevation = $result['elevation'] ?? 0;
50
51        if (!\is_int($latitude) && !\is_float($latitude) || !\is_int($longitude) && !\is_float($longitude)) {
52            return null;
53        }
54
55        try {
56            return new GeoLocation($latitude, $longitude, \is_int($elevation) || \is_float($elevation) ? $elevation : 0.0);
57        } catch (SunException) {
58            return null;
59        }
60    }
61}