Lines 100.00% 8 / 8
Functions and Methods 100.00% 5 / 5
Classes and Traits 100.00% 1 / 1
Name Lines Functions and Methods CRAP Classes and Traits
TcpControlAddress 100.00% 8 / 8 100.00% 5 / 5 9 100.00% 1 / 1
 __construct 100.00% 4 / 4 100.00% 1 / 1 4
 isLoopback 100.00% 1 / 1 100.00% 1 / 1 1
 toConnectableAddress 100.00% 1 / 1 100.00% 1 / 1 2
 resolveSocketAddress 100.00% 1 / 1 100.00% 1 / 1 1
 __toString 100.00% 1 / 1 100.00% 1 / 1 1
1<?php
2
3declare(strict_types=1);
4
5namespace Stewart\Runtime\Config;
6
7use Stewart\Runtime\Exception\ConfigurationException;
8
9final readonly class TcpControlAddress extends ControlAddress
10{
11    private const array WILDCARD_HOSTS = ['0.0.0.0', '::', '[::]', '*'];
12
13    private const array LOOPBACK_HOSTS = ['127.0.0.1', '::1', '[::1]', 'localhost'];
14
15    /** @throws ConfigurationException */
16    public function __construct(
17        public string $host,
18        public int $port,
19    ) {
20        if ($host === '') {
21            throw ConfigurationException::valueInvalid((string) $this, 'a TCP control address with a host and a port');
22        }
23
24        if ($port < 1 || $port > 65535) {
25            throw ConfigurationException::valueInvalid((string) $this, 'a TCP control address with a port in 1-65535');
26        }
27    }
28
29    public function isLoopback(): bool
30    {
31        return \in_array($this->host, self::LOOPBACK_HOSTS, true);
32    }
33
34    public function toConnectableAddress(): self
35    {
36        return \in_array($this->host, self::WILDCARD_HOSTS, true) ? new self('127.0.0.1', $this->port) : $this;
37    }
38
39    public function resolveSocketAddress(ProjectRoot $projectRoot): string
40    {
41        return (string) $this;
42    }
43
44    public function __toString(): string
45    {
46        return \sprintf('tcp://%s:%d', $this->host, $this->port);
47    }
48}