Lines 100.00% 23 / 23
Functions and Methods 100.00% 3 / 3
Classes and Traits 100.00% 1 / 1
Name Lines Functions and Methods CRAP Classes and Traits
MqttConfig 100.00% 23 / 23 100.00% 3 / 3 9 100.00% 1 / 1
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 fromSection 100.00% 13 / 13 100.00% 1 / 1 5
 readWill 100.00% 9 / 9 100.00% 1 / 1 3
1<?php
2
3declare(strict_types=1);
4
5namespace Stewart\Runtime\Config;
6
7use SensitiveParameter;
8use Stewart\Contracts\Mqtt\MqttMessage;
9use Stewart\Contracts\Mqtt\MqttQos;
10use Stewart\Contracts\Time\Duration;
11use Stewart\Runtime\Exception\ConfigurationException;
12
13final readonly class MqttConfig
14{
15    private const string CLIENT_ID_PREFIX = 'stewart-';
16
17    public function __construct(
18        public MqttServerUrl $serverUrl,
19        public string $clientId,
20        public Duration $keepalive,
21        public Duration $connectTimeout,
22        public BackoffPolicy $reconnectBackoff,
23        public int $outboundBuffer,
24        public ?MqttMessage $will,
25    ) {}
26
27    /** @throws ConfigurationException */
28    public static function fromSection(#[SensitiveParameter] ConfigSection $mqtt): ?self
29    {
30        $url = $mqtt->findString('url');
31
32        if ($url === null || $url === '') {
33            return null;
34        }
35
36        $clientId = $mqtt->findString('client_id');
37
38        return new self(
39            serverUrl: $mqtt->readParsedValue('url', MqttServerUrl::parse(...)),
40            clientId: $clientId === null || $clientId === '' ? self::CLIENT_ID_PREFIX . gethostname() : $clientId,
41            keepalive: $mqtt->readDuration('keepalive', Duration::seconds(1)),
42            connectTimeout: $mqtt->readDuration('connect_timeout', Duration::milliseconds(1)),
43            reconnectBackoff: $mqtt->readBackoff('reconnect_'),
44            outboundBuffer: $mqtt->readInt('outbound_buffer'),
45            will: self::readWill($mqtt->readSection('will')),
46        );
47    }
48
49    /** @throws ConfigurationException */
50    private static function readWill(ConfigSection $will): ?MqttMessage
51    {
52        $topic = $will->findString('topic');
53
54        if ($topic === null || $topic === '') {
55            return null;
56        }
57
58        return $will->readParsedValue('topic', static fn(string $topic): MqttMessage => MqttMessage::createForPublish(
59            $topic,
60            $will->readString('payload'),
61            MqttQos::from($will->readInt('qos')),
62            $will->readBool('retain'),
63        ));
64    }
65}