Lines 70.00% 7 / 10
Functions and Methods 33.33% 1 / 3
Classes and Traits 0.00% 0 / 1
Name Lines Functions and Methods CRAP Classes and Traits
RedisStoreBackendFactory 70.00% 7 / 10 33.33% 1 / 3 8.32 0.00% 0 / 1
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 listSchemes 0.00% 0 / 1 0.00% 0 / 1 2
 createBackend 75.00% 6 / 8 0.00% 0 / 1 5.39
1<?php
2
3declare(strict_types=1);
4
5namespace Stewart\Store\Redis;
6
7use Amp\Redis\RedisConfig;
8use Amp\Redis\RedisException;
9use Stewart\Store\Exception\StoreSetupException;
10use Stewart\Store\StoreBackend;
11use Stewart\Store\StoreBackendFactory;
12use Stewart\Store\StoreDsn;
13use Stewart\Store\StoreTiming;
14use Stewart\Support\Time\Deadlines;
15
16use function Amp\Redis\createRedisClient;
17
18final readonly class RedisStoreBackendFactory implements StoreBackendFactory
19{
20    private const string TCP_SCHEME = 'redis';
21
22    private const string SOCKET_SCHEME = 'unix';
23
24    public function __construct(private Deadlines $deadlines) {}
25
26    public function listSchemes(): array
27    {
28        return [self::TCP_SCHEME, self::SOCKET_SCHEME];
29    }
30
31    public function createBackend(StoreDsn $dsn, StoreTiming $timing): StoreBackend
32    {
33        if (!\in_array($dsn->scheme, $this->listSchemes(), true)) {
34            throw StoreSetupException::schemeUnsupported($dsn->scheme, $this->listSchemes());
35        }
36
37        if ($dsn->scheme === self::TCP_SCHEME && !\is_string(parse_url($dsn->reveal(), \PHP_URL_HOST))) {
38            throw StoreSetupException::dsnInvalid($dsn->reveal());
39        }
40
41        try {
42            $config = RedisConfig::fromUri($dsn->reveal(), $timing->timeout->toSeconds());
43        } catch (RedisException) {
44            // Not chained: amphp's message contains the URI and its password.
45            throw StoreSetupException::dsnInvalid($dsn->reveal());
46        }
47
48        return new RedisStoreBackend(createRedisClient($config), $dsn, $timing, $this->deadlines);
49    }
50}