Lines 96.00% 24 / 25
Methods 75.00% 3 / 4
Classes 0.00% 0 / 1
Name Lines Methods CRAP
 handledClass 100.00% 1 / 1 100.00% 1 / 1 1
 keySuffix 100.00% 1 / 1 100.00% 1 / 1 1
 encodeValue 100.00% 9 / 9 100.00% 1 / 1 7
 decodeValue 92.85% 13 / 14 0.00% 0 / 1 9.03
14final readonly class SelectorConverter implements ValueConverter
15{
16    public function handledClass(): string
17    {
18        return Selector::class;
19    }
20
21    public function keySuffix(): string
22    {
23        return '';
24    }
25
26    /** @return array<string, mixed> */
27    public function encodeValue(object $value): array
28    {
29        \assert($value instanceof Selector);
30
31        if ($value->isAny()) {
32            return ['kind' => 'any'];
33        }
34
35        return match ($value->getKind()) {
36            SelectorKind::Exact => ['kind' => 'exact', 'value' => $value->getPattern()],
37            SelectorKind::Glob => ['kind' => 'glob', 'pattern' => $value->getPattern()],
38            SelectorKind::Regex => ['kind' => 'regex', 'regex' => $value->getPattern()],
39            SelectorKind::MqttFilter => ['kind' => 'mqtt_filter', 'filter' => $value->getPattern()],
40            SelectorKind::AnyOf => ['kind' => 'any_of', 'selectors' => $value->listMembers()->mapToList($this->encodeValue(...))],
41        };
42    }
43
44    /** @throws JsonShapeException|SelectorException */
45    public function decodeValue(mixed $value, string $path): Selector
46    {
47        if (!\is_array($value)) {
48            throw JsonShapeException::wrongType($path, 'an object', get_debug_type($value));
49        }
50
51        $kind = JsonShape::requireString($value, 'kind');
52
53        return match ($kind) {
54            'exact' => Selector::exact(JsonShape::requireString($value, 'value')),
55            'glob' => Selector::glob(JsonShape::requireString($value, 'pattern')),
56            'regex' => Selector::regex(JsonShape::requireString($value, 'regex')),
57            'mqtt_filter' => Selector::mqttFilter(JsonShape::requireString($value, 'filter')),
58            'any' => Selector::any(),
59            'any_of' => Selector::anyOf(...array_map(
60                fn(array $selector): Selector => $this->decodeValue($selector, $path . '.selectors'),
61                JsonShape::requireObjectList($value, 'selectors'),
62            )),
63            default => throw JsonShapeException::unexpectedValue($path . '.kind', 'a selector kind', $kind),
64        };
65    }
66}